1  /-
  2  Copyright (c) 2014 Floris van Doorn. All rights reserved.
  3  Released under Apache 2.0 license as described in the file LICENSE.
  4  Authors: Floris van Doorn, Leonardo de Moura, Jeremy Avigad, Mario Carneiro
  5  -/
  6  import logic.basic algebra.ordered_ring data.option.basic algebra.order_functions
src         └─────────┘ └──────────────────┘ └───────────────┘ └─────────────────────┘
  7  
  8  /-!
  9  # Basic operations on the natural numbers
 10  
 11  This files has some basic lemmas about natural numbers, definition of the `choice` function,
 12  and extra recursors:
 13  
 14  * `le_rec_on`, `le_induction`: recursion and induction principles starting at non-zero numbers.
 15  * `decreasing_induction` : recursion gowing downwards.
 16  * `strong_rec'` : recursion based on strong inequalities.
 17  -/
 18  
 19  universes u v
 20  
 21  namespace nat
 22  variables {m n k : ℕ}
id                      
src                     
typ                     
 23  
 24  -- Sometimes a bare `nat.add` or similar appears as a consequence of unfolding
 25  -- during pattern matching. These lemmas package them back up as typeclass
 26  -- mediated operations.
 27  @[simp] theorem add_def {a b : ℕ} : nat.add a b = a + b := rfl
id                                      └─────┘          └─┘
src                                     └─────┘              └─┘
typ                                     └─────┘          └─┘
doc    └──┘
 28  @[simp] theorem mul_def {a b : ℕ} : nat.mul a b = a * b := rfl
id                                      └─────┘          └─┘
src                                     └─────┘              └─┘
typ                                     └─────┘          └─┘
doc    └──┘
 29  
 30  attribute [simp] nat.add_sub_cancel nat.add_sub_cancel_left
id                    └────────────────┘ └─────────────────────┘
src                   └────────────────┘ └─────────────────────┘
typ                   └────────────────┘ └─────────────────────┘
doc             └──┘
 31  attribute [simp] nat.sub_self
id                    └──────────┘
src                   └──────────┘
typ                   └──────────┘
doc             └──┘
 32  
 33  @[simp] lemma succ_pos' {n : ℕ} : 0 < succ n := succ_pos n
id                                       └──┘     └──────┘ 
src                                      └──┘      └──────┘
typ                                      └──┘     └──────┘ 
doc    └──┘
 34  
 35  theorem succ_inj' {n m : ℕ} : succ n = succ m ↔ n = m :=
id                                └──┘   └──┘     
src                               └──┘    └──┘      
typ                               └──┘   └──┘     
 36  ⟨succ_inj, congr_arg _⟩
id    └──────┘  └───────┘
src   └──────┘  └───────┘
typ   └──────┘  └───────┘
 37  
 38  theorem succ_le_succ_iff {m n : ℕ} : succ m ≤ succ n ↔ m ≤ n :=
id                                       └──┘   └──┘     
src                                      └──┘    └──┘      
typ                                      └──┘   └──┘     
 39  ⟨le_of_succ_le_succ, succ_le_succ⟩
id    └────────────────┘  └──────────┘
src   └────────────────┘  └──────────┘
typ   └────────────────┘  └──────────┘
 40  
 41  lemma zero_max {m : nat} : max 0 m = m :=
id                       └─┘    └─┘     
src                      └─┘    └─┘     
typ                      └─┘    └─┘     
 42  max_eq_right (zero_le _)
id   └──────────┘  └─────┘
src  └──────────┘  └─────┘
typ  └──────────┘  └─────┘
 43  
 44  theorem max_succ_succ {m n : ℕ} :
id                                
src                               
typ                               
 45    max (succ m) (succ n) = succ (max m n) :=
id     └─┘  └──┘    └──┘    └──┘  └─┘  
src    └─┘  └──┘     └──┘     └──┘  └─┘
typ    └─┘  └──┘    └──┘    └──┘  └─┘  
 46  begin
st   └─────
 47    by_cases h1 : m ≤ n,
id                     
src    └───────┘  └─┘ 
typ    └───────┘  └─┘
doc    └───────┘  └─┘  
txt    └───────┘  └─┘  
par    └───────┘  └─┘  
pid              └─┘  
st   ────────────────────┘└─
 48    rw [max_eq_right h1, max_eq_right (succ_le_succ h1)],
id         └──────────┘ └┘  └──────────┘  └──────────┘ └┘
src    └──┘└──────────┘  └┘└──────────┘ └──────────┘  └┘
typ    └──┘└──────────┘└┘└┘└──────────┘ └──────────┘└┘└┘
doc    └──┘              └┘                           └┘
txt    └──┘              └┘                           └┘
par    └──┘              └┘                           └┘
pid      └┘              └┘                           └┘
st   ────────────────────┘└──────────────────────────────┘└──
 49    { rw not_le at h1, have h2 := le_of_lt h1,
id          └────┘                   └──────┘ └┘
src      └─┘└────┘└────┘  └─────────┘└──────┘
typ      └─┘└────┘└────┘  └─────────┘└──────┘└┘
doc      └─┘      └────┘  └─────────┘        
txt      └─┘      └────┘  └─────────┘        
par      └─┘      └────┘  └─────────┘        
pid              └────┘  └─────┘└─┘        
st   ──────────────────┘└──────────────────────┘└─
 50      rw [max_eq_left h2, max_eq_left (succ_le_succ h2)] }
id           └─────────┘ └┘  └─────────┘  └──────────┘ └┘
src      └──┘└─────────┘  └┘└─────────┘ └──────────┘  └─┘
typ      └──┘└─────────┘└┘└┘└─────────┘ └──────────┘└┘└─┘
doc      └──┘             └┘                          └─┘
txt      └──┘             └┘                          └─┘
par      └──┘             └┘                          └─┘
pid        └┘             └┘                          └┘
st   ─────────────────────┘└─────────────────────────────┘└─
 51  end
st   ──┘
 52  
 53  lemma not_succ_lt_self {n : ℕ} : ¬succ n < n :=
id                                   └──┘   
src                                  └──┘   
typ                                  └──┘   
 54  not_lt_of_ge (nat.le_succ _)
id   └──────────┘  └─────────┘
src  └──────────┘  └─────────┘
typ  └──────────┘  └─────────┘
 55  
 56  theorem lt_succ_iff {m n : ℕ} : m < succ n ↔ m ≤ n :=
id                                    └──┘     
src                                    └──┘      
typ                                   └──┘     
 57  succ_le_succ_iff
id   └──────────────┘
src  └──────────────┘
typ  └──────────────┘
 58  
 59  lemma succ_le_iff {m n : ℕ} : succ m ≤ n ↔ m < n :=
id                                └──┘       
src                               └──┘         
typ                               └──┘       
 60  ⟨lt_of_succ_le, succ_le_of_lt⟩
id    └───────────┘  └───────────┘
src   └───────────┘  └───────────┘
typ   └───────────┘  └───────────┘
 61  
 62  lemma lt_iff_add_one_le {m n : ℕ} : m < n ↔ m + 1 ≤ n :=
id                                               
src                                                
typ                                              
 63  by rw succ_le_iff
id         └─────────┘
src     └─┘└─────────┘
typ     └─┘└─────────┘
doc     └─┘           
txt     └─┘           
par     └─┘           
pid                  
st     └───────────────
 64  
src  
typ  
doc  
txt  
par  
pid  
st   
 65  -- Just a restatement of `nat.lt_succ_iff` using `+1`.
src  ──────────────────────────────────────────────────────┘
typ  ──────────────────────────────────────────────────────┘
doc  ──────────────────────────────────────────────────────┘
txt  ──────────────────────────────────────────────────────┘
par  ──────────────────────────────────────────────────────┘
pid  ──────────────────────────────────────────────────────┘
st   ──────────────────────────────────────────────────────┘
 66  lemma lt_add_one_iff {a b : ℕ} : a < b + 1 ↔ a ≤ b :=
id                                            
src                                             
typ                                           
 67  nat.lt_succ_iff
id   └─────────────┘
src  └─────────────┘
typ  └─────────────┘
 68  
 69  -- A flipped version of `lt_add_one_iff`.
 70  lemma lt_one_add_iff {a b : ℕ} : a < 1 + b ↔ a ≤ b :=
id                                            
src                                             
typ                                           
 71  by simp only [add_comm, nat.lt_succ_iff]
id                 └──────┘  └─────────────┘
src     └─────────┘└──────┘└┘└─────────────┘└─
typ     └─────────┘└──────┘└┘└─────────────┘└─
doc     └─────────┘        └┘               └─
txt     └─────────┘        └┘               └─
par     └─────────┘        └┘               └─
pid         └──┘└┘        └┘               
st     └──────────────────────────────────────
 72  
src  
typ  
doc  
txt  
par  
pid  
st   
 73  theorem of_le_succ {n m : ℕ} (H : n ≤ m.succ) : n ≤ m ∨ n = m.succ :=
id                                      └───┘          └───┘
src                                       └───┘              └───┘
typ                                     └───┘          └───┘
 74  (lt_or_eq_of_le H).imp le_of_lt_succ id
id    └────────────┘  └─┘  └───────────┘ └┘
src   └────────────┘   └─┘  └───────────┘ └┘
typ   └────────────┘  └─┘  └───────────┘ └┘
 75  
 76  /-- Recursion starting at a non-zero number: given a map `C k → C (k+1)` for each `k`,
 77  there is a map from `C n` to each `C m`, `n ≤ m`. -/
 78  @[elab_as_eliminator]
doc    └────────────────┘
 79  def le_rec_on {C : ℕ → Sort u} {n : ℕ} : Π {m : ℕ}, n ≤ m → (Π {k}, C k → C (k+1)) → C n → C m
id                                                                               
src                                                                            
typ                                                                              
 80  | 0     H next x := eq.rec_on (eq_zero_of_le_zero H) x
id                     └───────┘  └────────────────┘
src                      └───────┘  └────────────────┘
typ                    └───────┘  └────────────────┘
 81  | (m+1) H next x := or.by_cases (of_le_succ H) (λ h : n ≤ m, next $ le_rec_on h @next x) (λ h : n = m + 1, eq.rec_on h x)
id          └──┘     └─────────┘  └────────┘                       └───────┘                          └───────┘ 
src                     └─────────┘  └────────┘                                                             └───────┘
typ         └──┘     └─────────┘  └────────┘                       └───────┘                          └───────┘ 
 82  
 83  theorem le_rec_on_self {C : ℕ → Sort u} {n} {h : n ≤ n} {next} (x : C n) : (le_rec_on h next x : C n) = x :=
id                                                                         └───────┘  └──┘        
src                                                                            └───────┘                 
typ                                                                        └───────┘  └──┘        
doc                                                                              └───────┘
 84  by cases n; unfold le_rec_on or.by_cases; rw [dif_neg n.not_succ_le_self, dif_pos rfl]
id                                                └─────┘ └────────────────┘  └─────┘ └─┘
src     └────┘   └──────────────────────────┘  └──┘└─────┘└────────────────┘└┘└─────┘└─┘└─
typ     └────┘  └──────────────────────────┘  └──┘└─────┘└────────────────┘└┘└─────┘└─┘└─
doc     └────┘   └──────────────────────────┘  └──┘                         └┘          └─
txt     └────┘   └──────────────────────────┘  └──┘                         └┘          └─
par     └────┘   └──────────────────────────┘  └──┘                         └┘          └─
pid                   └────────────────────┘    └┘                         └┘          
st     └──────────────────────────────────────────┘└────────────────────────┘└───────────┘
 85  
src  
typ  
doc  
txt  
par  
pid  
st   
 86  theorem le_rec_on_succ {C : ℕ → Sort u} {n m} (h1 : n ≤ m) {h2 : n ≤ m+1} {next} (x : C n) :
id                                                                                  
src                                                                     
typ                                                                                 
 87    (le_rec_on h2 @next x : C (m+1)) = next (le_rec_on h1 @next x : C m) :=
id      └───────┘ └┘  └──┘           └──┘  └───────┘ └┘  └──┘     
src     └───────┘                             └───────┘
typ     └───────┘ └┘  └──┘           └──┘  └───────┘ └┘  └──┘     
doc     └───────┘                               └───────┘
 88  by conv { to_lhs, rw [le_rec_on, or.by_cases, dif_pos h1] }
id                         └───────┘  └─────────┘  └─────┘ └┘
src     └─────┘└────┘└┘└──┘└───────┘└┘└─────────┘└┘└─────┘  └┘└─
typ     └─────┘└────┘└┘└──┘└───────┘└┘└─────────┘└┘└─────┘└┘└┘└─
doc                        └───────┘
txt     └─────┘└────┘└┘└──┘         └┘           └┘         └┘└─
par     └─────┘└────┘└┘└──┘         └┘           └┘         └┘└─
pid         └────────────┘         └┘           └┘         └─┘
st     └─────┘└─────┘└─────────────┘└───────────┘└──────────┘ 
 89  
src  
typ  
txt  
par  
pid  
st   
 90  theorem le_rec_on_succ' {C : ℕ → Sort u} {n} {h : n ≤ n+1} {next} (x : C n) :
id                                                                      
src                                                       
typ                                                                     
 91    (le_rec_on h next x : C (n+1)) = next x :=
id      └───────┘  └──┘           └──┘ 
src     └───────┘                    
typ     └───────┘  └──┘           └──┘ 
doc     └───────┘
 92  by rw [le_rec_on_succ (le_refl n), le_rec_on_self]
id          └────────────┘  └─────┘    └────────────┘
src     └──┘└────────────┘ └─────┘ └─┘└────────────┘└─
typ     └──┘└────────────┘ └─────┘└─┘└────────────┘└─
doc     └──┘                       └─┘              └─
txt     └──┘                       └─┘              └─
par     └──┘                       └─┘              └─
pid       └┘                       └─┘              
st     └─────────────────────────────┘└──────────────┘
 93  
src  
typ  
doc  
txt  
par  
pid  
st   
 94  theorem le_rec_on_trans {C : ℕ → Sort u} {n m k} (hnm : n ≤ m) (hmk : m ≤ k) {next} (x : C n) :
id                                                                                      
src                                                                        
typ                                                                                     
 95    (le_rec_on (le_trans hnm hmk) @next x : C k) = le_rec_on hmk @next (le_rec_on hnm @next x) :=
id      └───────┘  └──────┘ └─┘ └─┘   └──┘        └───────┘ └─┘  └──┘  └───────┘ └─┘  └──┘ 
src     └───────┘  └──────┘                          └───────┘            └───────┘
typ     └───────┘  └──────┘ └─┘ └─┘   └──┘        └───────┘ └─┘  └──┘  └───────┘ └─┘  └──┘ 
doc     └───────┘                                     └───────┘            └───────┘
 96  begin
st   └─────
 97    induction hmk with k hmk ih, { rw le_rec_on_self },
id               └─┘                     └────────────┘
src    └────────┘   └────────────┘    └─┘└────────────┘
typ    └────────┘└─┘└────────────┘    └─┘└────────────┘
doc    └────────┘   └────────────┘    └─┘              
txt    └────────┘   └────────────┘    └─┘              
par    └────────┘   └────────────┘    └─┘              
pid                └───────────┘                    
st   ────────────────────────────┘└──┘└────────────────┘└┘
 98    rw [le_rec_on_succ (le_trans hnm hmk), ih, le_rec_on_succ]
id         └────────────┘  └──────┘ └─┘ └─┘   └┘  └────────────┘
src    └──┘└────────────┘ └──────┘      └─┘  └┘└────────────┘└┘
typ    └──┘└────────────┘ └──────┘└─┘└─┘└─┘└┘└┘└────────────┘└┘
doc    └──┘                             └─┘  └┘              └┘
txt    └──┘                             └─┘  └┘              └┘
par    └──┘                             └─┘  └┘              └┘
pid      └┘                             └─┘  └┘              
st   ──────────────────────────────────────┘└──┘└──────────────┘
 99  end
st   └─┘
100  
101  theorem le_rec_on_succ_left {C : ℕ → Sort u} {n m} (h1 : n ≤ m) (h2 : n+1 ≤ m)
id                                                                        
src                                                                         
typ                                                                       
102    {next : Π{{k}}, C k → C (k+1)} (x : C n) :
id                                    
src                              
typ                                   
103    (le_rec_on h2 next (next x) : C m) = (le_rec_on h1 next x : C m) :=
id      └───────┘ └┘ └──┘  └──┘          └───────┘ └┘ └──┘     
src     └───────┘                           └───────┘
typ     └───────┘ └┘ └──┘  └──┘          └───────┘ └┘ └──┘     
doc     └───────┘                            └───────┘
104  begin
st   └─────
105    rw [subsingleton.elim h1 (le_trans (le_succ n) h2),
id         └───────────────┘ └┘  └──────┘  └─────┘   └┘
src    └──┘└───────────────┘   └──────┘ └─────┘ └┘  └──
typ    └──┘└───────────────┘└┘ └──────┘ └─────┘└┘└┘└──
doc    └──┘                                     └┘  └──
txt    └──┘                                     └┘  └──
par    └──┘                                     └┘  └──
pid      └┘                                     └┘  └──
st   ───────────────────────────────────────────────────┘└─
106        le_rec_on_trans (le_succ n) h2, le_rec_on_succ']
id         └─────────────┘  └─────┘   └┘  └─────────────┘
src  ─────┘└─────────────┘ └─────┘ └┘  └┘└─────────────┘└┘
typ  ─────┘└─────────────┘ └─────┘└┘└┘└┘└─────────────┘└┘
doc  ─────┘                        └┘  └┘               └┘
txt  ─────┘                        └┘  └┘               └┘
par  ─────┘                        └┘  └┘               └┘
pid  ─────┘                        └┘  └┘               
st   ───────────────────────────────────┘└───────────────┘
107  end
st   └─┘
108  
109  theorem le_rec_on_injective {C : ℕ → Sort u} {n m} (hnm : n ≤ m)
id                                                              
src                                                             
typ                                                             
110    (next : Π n, C n → C (n+1)) (Hnext : ∀ n, function.injective (next n)) :
id                                        └────────────────┘  └──┘ 
src                                             └────────────────┘
typ                                       └────────────────┘  └──┘ 
111    function.injective (le_rec_on hnm next) :=
id     └────────────────┘  └───────┘ └─┘ └──┘
src    └────────────────┘  └───────┘
typ    └────────────────┘  └───────┘ └─┘ └──┘
doc                        └───────┘
112  begin
st   └─────
113    induction hnm with m hnm ih, { intros x y H, rwa [le_rec_on_self, le_rec_on_self] at H },
id               └─┘                                     └────────────┘  └────────────┘
src    └────────┘   └────────────┘    └──────────┘  └───┘└────────────┘└┘└────────────┘└─────┘
typ    └────────┘└─┘└────────────┘    └──────────┘  └───┘└────────────┘└┘└────────────┘└─────┘
doc    └────────┘   └────────────┘    └──────────┘  └───┘              └┘              └─────┘
txt    └────────┘   └────────────┘    └──────────┘  └───┘              └┘              └─────┘
par    └────────┘   └────────────┘    └──────────┘  └───┘              └┘              └─────┘
pid                └───────────┘          └────┘     └┘              └┘              └───┘
st   ────────────────────────────┘└──┘└──────────┘└───────────────────┘└──────────────┘└────┘└┘
114    intros x y H, rw [le_rec_on_succ hnm, le_rec_on_succ hnm] at H, exact ih (Hnext _ H)
id                       └────────────┘ └─┘  └────────────┘ └─┘              └┘  └───┘   
src    └──────────┘  └──┘└────────────┘   └┘└────────────┘   └────┘  └────┘        └─┘ └┘
typ    └──────────┘  └──┘└────────────┘└─┘└┘└────────────┘└─┘└────┘  └────┘└┘ └───┘└─┘└┘
doc    └──────────┘  └──┘                 └┘                 └────┘  └────┘        └─┘ └┘
txt    └──────────┘  └──┘                 └┘                 └────┘  └────┘        └─┘ └┘
par    └──────────┘  └──┘                 └┘                 └────┘  └────┘        └─┘ └┘
pid          └────┘    └┘                 └┘                 └───┘               └─┘ 
st   ─────────────┘└──────────────────────┘└──────────────────┘└───┘└─────────────────────┘
115  end
st   └─┘
116  
117  theorem le_rec_on_surjective {C : ℕ → Sort u} {n m} (hnm : n ≤ m)
id                                                               
src                                                              
typ                                                              
118    (next : Π n, C n → C (n+1)) (Hnext : ∀ n, function.surjective (next n)) :
id                                        └─────────────────┘  └──┘ 
src                                             └─────────────────┘
typ                                       └─────────────────┘  └──┘ 
119    function.surjective (le_rec_on hnm next) :=
id     └─────────────────┘  └───────┘ └─┘ └──┘
src    └─────────────────┘  └───────┘
typ    └─────────────────┘  └───────┘ └─┘ └──┘
doc                         └───────┘
120  begin
st   └─────
121    induction hnm with m hnm ih, { intros x, use x, rw le_rec_on_self },
id               └─┘                                     └────────────┘
src    └────────┘   └────────────┘    └──────┘  └──┘   └─┘└────────────┘
typ    └────────┘└─┘└────────────┘    └──────┘  └──┘  └─┘└────────────┘
doc    └────────┘   └────────────┘    └──────┘  └──┘   └─┘              
txt    └────────┘   └────────────┘    └──────┘  └──┘   └─┘              
par    └────────┘   └────────────┘    └──────┘  └──┘   └─┘              
pid                └───────────┘          └┘                        
st   ────────────────────────────┘└──┘└──────┘└─────┘└──────────────────┘└┘
122    intros x, rcases Hnext _ x with ⟨w, rfl⟩, rcases ih w with ⟨x, rfl⟩, use x, rw le_rec_on_succ
id                      └───┘                          └┘                          └────────────┘
src    └──────┘  └─────┘     └─┘ └────────────┘  └─────┘   └────────────┘  └──┘   └─┘└────────────┘
typ    └──────┘  └─────┘└───┘└─┘└────────────┘  └─────┘└┘└────────────┘  └──┘  └─┘└────────────┘
doc    └──────┘  └─────┘     └─┘ └────────────┘  └─────┘   └────────────┘  └──┘   └─┘              
txt    └──────┘  └─────┘     └─┘ └────────────┘  └─────┘   └────────────┘  └──┘   └─┘              
par    └──────┘  └─────┘     └─┘ └────────────┘  └─────┘   └────────────┘  └──┘   └─┘              
pid          └┘             └─┘ └────────────┘           └────────────┘                        
st   ─────────┘└──────────────────────────────┘└─────────────────────────┘└─────┘└──────────────────┘
123  end
st   └─┘
124  
125  theorem pred_eq_of_eq_succ {m n : ℕ} (H : m = n.succ) : m.pred = n := by simp [H]
id                                              └───┘    └───┘               
src                                               └───┘     └───┘          └────┘ └─
typ                                             └───┘    └───┘         └────┘└─
doc                                                                           └────┘ └─
txt                                                                           └────┘ └─
par                                                                           └────┘ └─
pid                                                                                
st                                                                           └─────────
126  
src  
typ  
doc  
txt  
par  
pid  
st   
127  @[simp] lemma pred_eq_succ_iff {n m : ℕ} : pred n = succ m ↔ n = m + 2 :=
id                                             └──┘   └──┘      
src                                            └──┘    └──┘         
typ                                            └──┘   └──┘      
doc    └──┘
128  by cases n; split; rintro ⟨⟩; refl
id            
src     └────┘   └───┘  └───────┘  └────
typ     └────┘  └───┘  └───────┘  └────
doc     └────┘   └───┘  └───────┘  └────
txt     └────┘   └───┘  └───────┘  └────
par     └────┘   └───┘  └───────┘  └────
pid                          └─┘      
st     └────────────────────────────────
129  
src  
typ  
doc  
txt  
par  
pid  
st   
130  theorem pred_sub (n m : ℕ) : pred n - m = pred (n - m) :=
id                               └──┘     └──┘    
src                              └──┘       └──┘    
typ                              └──┘     └──┘    
131  by rw [← sub_one, nat.sub_sub, one_add]; refl
id            └─────┘  └─────────┘  └─────┘
src     └────┘└─────┘└┘└─────────┘└┘└─────┘  └────
typ     └────┘└─────┘└┘└─────────┘└┘└─────┘  └────
doc     └────┘       └┘           └┘         └────
txt     └────┘       └┘           └┘         └────
par     └────┘       └┘           └┘         └────
pid       └──┘       └┘           └┘             
st     └────────────┘└───────────┘└───────┘└──────
132  
src  
typ  
doc  
txt  
par  
pid  
st   
133  lemma pred_eq_sub_one (n : ℕ) : pred n = n - 1 := rfl
id                                  └──┘          └─┘
src                                 └──┘            └─┘
typ                                 └──┘          └─┘
st                                                     └─┘
134  
135  lemma one_le_of_lt {n m : ℕ} (h : n < m) : 1 ≤ m :=
id                                             
src                                             
typ                                            
136  lt_of_le_of_lt (nat.zero_le _) h
id   └────────────┘  └─────────┘    
src  └────────────┘  └─────────┘
typ  └────────────┘  └─────────┘    
137  
138  lemma le_pred_of_lt {n m : ℕ} (h : m < n) : m ≤ n - 1 :=
id                                              
src                                                 
typ                                             
139  nat.sub_le_sub_right h 1
id   └──────────────────┘ 
src  └──────────────────┘
typ  └──────────────────┘ 
140  
141  lemma le_of_pred_lt {m n : ℕ} : pred m < n → m ≤ n :=
id                                  └──┘        
src                                 └──┘          
typ                                 └──┘        
142  match m with
id         
typ        
143  | 0 := le_of_lt
id          └──────┘
src         └──────┘
typ         └──────┘
144  | m+1 := id
id           └┘
src          └┘
typ          └┘
145  end
146  
147  /-- This ensures that `simp` succeeds on `pred (n + 1) = n`. -/
148  @[simp] lemma pred_one_add (n : ℕ) : pred (1 + n) = n :=
id                                       └──┘        
src                                      └──┘        
typ                                      └──┘        
doc    └──┘
149  by rw [add_comm, add_one, pred_succ]
id          └──────┘  └─────┘  └───────┘
src     └──┘└──────┘└┘└─────┘└┘└───────┘└─
typ     └──┘└──────┘└┘└─────┘└┘└───────┘└─
doc     └──┘        └┘       └┘         └─
txt     └──┘        └┘       └┘         └─
par     └──┘        └┘       └┘         └─
pid       └┘        └┘       └┘         
st     └───────────┘└───────┘└─────────┘
150  
src  
typ  
doc  
txt  
par  
pid  
st   
151  theorem pos_iff_ne_zero : 0 < n ↔ n ≠ 0 :=
id                                   
src                                    
typ                                  
152  ⟨ne_of_gt, nat.pos_of_ne_zero⟩
id    └──────┘  └────────────────┘
src   └──────┘  └────────────────┘
typ   └──────┘  └────────────────┘
153  
154  lemma one_lt_iff_ne_zero_and_ne_one : ∀ {n : ℕ}, 1 < n ↔ n ≠ 0 ∧ n ≠ 1
id                                                             
src                                                                
typ                                                            
155  | 0     := dec_trivial
id              └─────────┘
src             └─────────┘
typ             └─────────┘
doc             └─────────┘
156  | 1     := dec_trivial
id              └─────────┘
src             └─────────┘
typ             └─────────┘
doc             └─────────┘
157  | (n+2) := dec_trivial
id             └─────────┘
src            └─────────┘
typ            └─────────┘
doc             └─────────┘
158  
159  theorem eq_of_lt_succ_of_not_lt {a b : ℕ} (h1 : a < b + 1) (h2 : ¬ a < b) : a = b :=
id                                                                        
src                                                                           
typ                                                                       
160  have h3 : a ≤ b, from le_of_lt_succ h1,
id                      └───────────┘ └┘
src                       └───────────┘
typ                     └───────────┘ └┘
161  or.elim (eq_or_lt_of_not_lt h2) (λ h, h) (λ h, absurd h (not_lt_of_ge h3))
id   └─────┘  └────────────────┘ └┘              └────┘   └──────────┘ └┘
src  └─────┘  └────────────────┘                    └────┘    └──────────┘
typ  └─────┘  └────────────────┘ └┘              └────┘   └──────────┘ └┘
162  
163  protected theorem le_sub_add (n m : ℕ) : n ≤ n - m + m :=
id                                                 
src                                                  
typ                                                
164  or.elim (le_total n m)
id   └─────┘  └──────┘  
src  └─────┘  └──────┘
typ  └─────┘  └──────┘  
165    (assume : n ≤ m, begin rw [sub_eq_zero_of_le this, zero_add], exact this end)
id                             └───────────────┘ └──┘  └──────┘         └──┘
src                          └──┘└───────────────┘    └┘└──────┘  └────┘    
typ                        └──┘└───────────────┘└──┘└┘└──────┘  └────┘└──┘
doc                           └──┘                     └┘          └────┘    
txt                           └──┘                     └┘          └────┘    
par                           └──┘                     └┘          └────┘    
pid                             └┘                     └┘                   
st                      └──────────────────────────────┘└────────┘└────────────┘└─┘
166    (assume : m ≤ n, begin rw (nat.sub_add_cancel this) end)
id                             └────────────────┘ └──┘
src                          └─┘ └────────────────┘    └┘
typ                        └─┘ └────────────────┘└──┘└┘
doc                           └─┘                       └┘
txt                           └─┘                       └┘
par                           └─┘                       └┘
pid                                                    
st                      └─────────────────────────────────┘└─┘
167  
168  theorem sub_add_eq_max (n m : ℕ) : n - m + m = max n m :=
id                                           └─┘  
src                                             └─┘
typ                                          └─┘  
169  eq_max (nat.le_sub_add _ _) (le_add_left _ _) $ λ k h₁ h₂,
id   └────┘  └────────────┘       └─────────┘           └┘ └┘
src  └────┘  └────────────┘       └─────────┘
typ  └────┘  └────────────┘       └─────────┘           └┘ └┘
170  by rw ← nat.sub_add_cancel h₂; exact
id           └────────────────┘ └┘
src     └───┘└────────────────┘    └────┘
typ     └───┘└────────────────┘└┘  └────┘
doc     └───┘                      └────┘
txt     └───┘                      └────┘
par     └───┘                      └────┘
pid       └─┘                           
st     └──────────────────────────────────
171  add_le_add_right (nat.sub_le_sub_right h₁ _) _
id   └──────────────┘  └──────────────────┘ └┘
src  └──────────────┘ └──────────────────┘  └─────
typ  └──────────────┘ └──────────────────┘└┘└─────
doc                                         └─────
txt                                         └─────
par                                         └─────
pid                                         └───┘
st   ───────────────────────────────────────────────
172  
src  
typ  
doc  
txt  
par  
pid  
st   
173  theorem sub_add_min (n m : ℕ) : n - m + min n m = n :=
id                                      └─┘    
src                                       └─┘     
typ                                     └─┘    
174  (le_total n m).elim
id    └──────┘   └──┘
src   └──────┘     └──┘
typ   └──────┘   └──┘
175    (λ h, by rw [min_eq_left h, sub_eq_zero_of_le h, zero_add])
id                 └─────────┘   └───────────────┘   └──────┘
src             └──┘└─────────┘ └┘└───────────────┘ └┘└──────┘
typ            └──┘└─────────┘└┘└───────────────┘└┘└──────┘
doc             └──┘            └┘                  └┘        
txt             └──┘            └┘                  └┘        
par             └──┘            └┘                  └┘        
pid               └┘            └┘                  └┘        
st             └────────────────┘└───────────────────┘└────────┘
176    (λ h, by rw [min_eq_right h, nat.sub_add_cancel h])
id                 └──────────┘   └────────────────┘ 
src             └──┘└──────────┘ └┘└────────────────┘ 
typ            └──┘└──────────┘└┘└────────────────┘
doc             └──┘             └┘                   
txt             └──┘             └┘                   
par             └──┘             └┘                   
pid               └┘             └┘                   
st             └─────────────────┘└────────────────────┘
177  
178  protected theorem add_sub_cancel' {n m : ℕ} (h : m ≤ n) : m + (n - m) = n :=
id                                                                 
src                                                                    
typ                                                                
179  by rw [add_comm, nat.sub_add_cancel h]
id          └──────┘  └────────────────┘ 
src     └──┘└──────┘└┘└────────────────┘ └─
typ     └──┘└──────┘└┘└────────────────┘└─
doc     └──┘        └┘                   └─
txt     └──┘        └┘                   └─
par     └──┘        └┘                   └─
pid       └┘        └┘                   
st     └───────────┘└────────────────────┘
180  
src  
typ  
doc  
txt  
par  
pid  
st   
181  protected theorem sub_eq_of_eq_add (h : k = m + n) : k - m = n :=
id                                                       
src                                                          
typ                                                      
182  begin rw [h, nat.add_sub_cancel_left] end
id               └─────────────────────┘
src        └──┘ └┘└─────────────────────┘└┘
typ        └──┘└┘└─────────────────────┘└┘
doc        └──┘ └┘                       └┘
txt        └──┘ └┘                       └┘
par        └──┘ └┘                       └┘
pid          └┘ └┘                       
st   └─────────┘└───────────────────────┘└─┘
183  
184  theorem sub_cancel {a b c : ℕ} (h₁ : a ≤ b) (h₂ : a ≤ c) (w : b - a = c - a) : b = c :=
id                                                                      
src                                                                             
typ                                                                     
185  by rw [←nat.sub_add_cancel h₁, ←nat.sub_add_cancel h₂, w]
id           └────────────────┘ └┘   └────────────────┘ └┘  
src     └───┘└────────────────┘  └─┘└────────────────┘  └┘ └─
typ     └───┘└────────────────┘└┘└─┘└────────────────┘└┘└┘└─
doc     └───┘                    └─┘                    └┘ └─
txt     └───┘                    └─┘                    └┘ └─
par     └───┘                    └─┘                    └┘ └─
pid       └─┘                    └─┘                    └┘ 
st     └─────────────────────────┘└──────────────────────┘└─┘
186  
src  
typ  
doc  
txt  
par  
pid  
st   
187  lemma sub_sub_sub_cancel_right {a b c : ℕ} (h₂ : c ≤ b) : (a - c) - (b - c) = a - b :=
id                                                                       
src                                                                            
typ                                                                      
188  by rw [nat.sub_sub, ←nat.add_sub_assoc h₂, nat.add_sub_cancel_left]
id          └─────────┘   └───────────────┘ └┘  └─────────────────────┘
src     └──┘└─────────┘└─┘└───────────────┘  └┘└─────────────────────┘└─
typ     └──┘└─────────┘└─┘└───────────────┘└┘└┘└─────────────────────┘└─
doc     └──┘           └─┘                   └┘                       └─
txt     └──┘           └─┘                   └┘                       └─
par     └──┘           └─┘                   └┘                       └─
pid       └┘           └─┘                   └┘                       
st     └──────────────┘└─────────────────────┘└───────────────────────┘
189  
src  
typ  
doc  
txt  
par  
pid  
st   
190  lemma add_sub_cancel_right (n m k : ℕ) : n + (m + k) - k = n + m :=
id                                                       
src                                                          
typ                                                      
191  by { rw [nat.add_sub_assoc, nat.add_sub_cancel], apply k.le_add_left }
id            └───────────────┘  └────────────────┘
src       └──┘└───────────────┘└┘└────────────────┘  └────┘             
typ       └──┘└───────────────┘└┘└────────────────┘  └────┘             
doc       └──┘                 └┘                    └────┘             
txt       └──┘                 └┘                    └────┘             
par       └──┘                 └┘                    └────┘             
pid         └┘                 └┘                                      
st     └──────────────────────┘└──────────────────┘└─────────────────────┘└┘
192  
193  protected lemma sub_add_eq_add_sub {a b c : ℕ} (h : b ≤ a) : (a - b) + c = (a + c) - b :=
id                                                                          
src                                                                               
typ                                                                         
194  by rw [add_comm a, nat.add_sub_assoc h, add_comm]
id          └──────┘   └───────────────┘   └──────┘
src     └──┘└──────┘ └┘└───────────────┘ └┘└──────┘└─
typ     └──┘└──────┘└┘└───────────────┘└┘└──────┘└─
doc     └──┘         └┘                  └┘        └─
txt     └──┘         └┘                  └┘        └─
par     └──┘         └┘                  └┘        └─
pid       └┘         └┘                  └┘        
st     └─────────────┘└───────────────────┘└────────┘
195  
src  
typ  
doc  
txt  
par  
pid  
st   
196  theorem sub_min (n m : ℕ) : n - min n m = n - m :=
id                                └─┘      
src                                └─┘        
typ                               └─┘      
197  nat.sub_eq_of_eq_add $ by rw [add_comm, sub_add_min]
id   └──────────────────┘          └──────┘  └─────────┘
src  └──────────────────┘      └──┘└──────┘└┘└─────────┘└─
typ  └──────────────────┘      └──┘└──────┘└┘└─────────┘└─
doc                            └──┘        └┘           └─
txt                            └──┘        └┘           └─
par                            └──┘        └┘           └─
pid                              └┘        └┘           
st                            └───────────┘└───────────┘
198  
src  
typ  
doc  
txt  
par  
pid  
st   
199  theorem sub_sub_assoc {a b c : ℕ} (h₁ : b ≤ a) (h₂ : c ≤ b) : a - (b - c) = a - b + c :=
id                                                                      
src                                                                             
typ                                                                     
200  (nat.sub_eq_iff_eq_add (le_trans (nat.sub_le _ _) h₁)).2 $
id    └───────────────────┘  └──────┘  └────────┘      └┘  
src   └───────────────────┘  └──────┘  └────────┘          
typ   └───────────────────┘  └──────┘  └────────┘      └┘  
201  by rw [add_right_comm, add_assoc, nat.sub_add_cancel h₂, nat.sub_add_cancel h₁]
id          └────────────┘  └───────┘  └────────────────┘ └┘  └────────────────┘ └┘
src     └──┘└────────────┘└┘└───────┘└┘└────────────────┘  └┘└────────────────┘  └─
typ     └──┘└────────────┘└┘└───────┘└┘└────────────────┘└┘└┘└────────────────┘└┘└─
doc     └──┘              └┘         └┘                    └┘                    └─
txt     └──┘              └┘         └┘                    └┘                    └─
par     └──┘              └┘         └┘                    └┘                    └─
pid       └┘              └┘         └┘                    └┘                    
st     └─────────────────┘└─────────┘└─────────────────────┘└─────────────────────┘
202  
src  
typ  
doc  
txt  
par  
pid  
st   
203  protected theorem lt_of_sub_pos (h : 0 < n - m) : m < n :=
id                                                   
src                                                    
typ                                                  
204  lt_of_not_ge
id   └──────────┘
src  └──────────┘
typ  └──────────┘
205    (assume : n ≤ m,
id                 
src                
typ                
206      have n - m = 0, from sub_eq_zero_of_le this,
id                        └───────────────┘ └──┘
src                         └───────────────┘
typ                       └───────────────┘ └──┘
207      begin rw this at h, exact lt_irrefl _ h end)
id                └──┘             └───────┘   
src            └─┘    └───┘  └────┘└───────┘└─┘ 
typ            └─┘└──┘└───┘  └────┘└───────┘└─┘
doc            └─┘    └───┘  └────┘         └─┘ 
txt            └─┘    └───┘  └────┘         └─┘ 
par            └─┘    └───┘  └────┘         └─┘ 
pid                  └───┘                └─┘ 
st       └────────────────┘└────────────────────┘└─┘
208  
209  protected theorem lt_of_sub_lt_sub_right : m - k < n - k → m < n :=
id                                                         
src                                                            
typ                                                        
210  lt_imp_lt_of_le_imp_le (λ h, nat.sub_le_sub_right h _)
id   └────────────────────┘      └──────────────────┘ 
src  └────────────────────┘       └──────────────────┘
typ  └────────────────────┘      └──────────────────┘ 
211  
212  protected theorem lt_of_sub_lt_sub_left : m - n < m - k → k < n :=
id                                                        
src                                                           
typ                                                       
213  lt_imp_lt_of_le_imp_le (nat.sub_le_sub_left _)
id   └────────────────────┘  └─────────────────┘
src  └────────────────────┘  └─────────────────┘
typ  └────────────────────┘  └─────────────────┘
214  
215  protected theorem sub_lt_self (h₁ : 0 < m) (h₂ : 0 < n) : m - n < m :=
id                                                             
src                                                               
typ                                                            
216  calc
217    m - n = succ (pred m) - succ (pred n) : by rw [succ_pred_eq_of_pos h₁, succ_pred_eq_of_pos h₂]
id          └──┘  └──┘    └──┘  └──┘            └─────────────────┘ └┘  └─────────────────┘ └┘
src           └──┘  └──┘     └──┘  └──┘         └──┘└─────────────────┘  └┘└─────────────────┘  └─
typ         └──┘  └──┘    └──┘  └──┘        └──┘└─────────────────┘└┘└┘└─────────────────┘└┘└─
doc                                               └──┘                     └┘                     └─
txt                                               └──┘                     └┘                     └─
par                                               └──┘                     └┘                     └─
pid                                                 └┘                     └┘                     
st                                               └─────────────────────────┘└──────────────────────┘
218      ... = pred m - pred n               : by rw succ_sub_succ
id             └──┘   └──┘                        └───────────┘
src  ───┘      └──┘    └──┘                      └─┘└───────────┘
typ  ───┘      └──┘   └──┘                     └─┘└───────────┘
doc  ───┘                                         └─┘             
txt  ───┘                                         └─┘             
par  ───┘                                         └─┘             
pid  ───┘                                                        
st   ───┘                                        └─────────────────
219      ... ≤ pred m                        : sub_le _ _
id             └──┘                           └────┘
src  ───┘      └──┘                            └────┘
typ  ───┘      └──┘                           └────┘
doc  ───┘
txt  ───┘
par  ───┘
pid  ───┘
st   ───┘
220      ... < succ (pred m)                 : lt_succ_self _
id             └──┘  └──┘                     └──────────┘
src            └──┘  └──┘                      └──────────┘
typ            └──┘  └──┘                     └──────────┘
221      ... = m                             : succ_pred_eq_of_pos h₁
id                                            └─────────────────┘ └┘
src                                            └─────────────────┘
typ                                           └─────────────────┘ └┘
222  
223  protected theorem le_sub_right_of_add_le (h : m + k ≤ n) : m ≤ n - k :=
id                                                             
src                                                                
typ                                                            
224  by rw ← nat.add_sub_cancel m k; exact nat.sub_le_sub_right h k
id           └────────────────┘          └──────────────────┘  
src     └───┘└────────────────┘    └────┘└──────────────────┘  
typ     └───┘└────────────────┘  └────┘└──────────────────┘
doc     └───┘                      └────┘                      
txt     └───┘                      └────┘                      
par     └───┘                      └────┘                      
pid       └─┘                                                 
st     └────────────────────────────────────────────────────────────
225  
src  
typ  
doc  
txt  
par  
pid  
st   
226  protected theorem le_sub_left_of_add_le (h : k + m ≤ n) : m ≤ n - k :=
id                                                            
src                                                               
typ                                                           
227  nat.le_sub_right_of_add_le (by rwa add_comm at h)
id   └────────────────────────┘         └──────┘
src  └────────────────────────┘     └──┘└──────┘└───┘
typ  └────────────────────────┘     └──┘└──────┘└───┘
doc                                 └──┘        └───┘
txt                                 └──┘        └───┘
par                                 └──┘        └───┘
pid                                            └───┘
st                                 └────────────────┘
228  
229  protected theorem lt_sub_right_of_add_lt (h : m + k < n) : m < n - k :=
id                                                             
src                                                                
typ                                                            
230  lt_of_succ_le $ nat.le_sub_right_of_add_le $
id   └───────────┘   └────────────────────────┘
src  └───────────┘   └────────────────────────┘
typ  └───────────┘   └────────────────────────┘
231  by rw succ_add; exact succ_le_of_lt h
id         └──────┘        └───────────┘ 
src     └─┘└──────┘  └────┘└───────────┘ 
typ     └─┘└──────┘  └────┘└───────────┘
doc     └─┘          └────┘              
txt     └─┘          └────┘              
par     └─┘          └────┘              
pid                                    
st     └───────────────────────────────────
232  
src  
typ  
doc  
txt  
par  
pid  
st   
233  protected theorem lt_sub_left_of_add_lt (h : k + m < n) : m < n - k :=
id                                                            
src                                                               
typ                                                           
234  nat.lt_sub_right_of_add_lt (by rwa add_comm at h)
id   └────────────────────────┘         └──────┘
src  └────────────────────────┘     └──┘└──────┘└───┘
typ  └────────────────────────┘     └──┘└──────┘└───┘
doc                                 └──┘        └───┘
txt                                 └──┘        └───┘
par                                 └──┘        └───┘
pid                                            └───┘
st                                 └────────────────┘
235  
236  protected theorem add_lt_of_lt_sub_right (h : m < n - k) : m + k < n :=
id                                                             
src                                                                
typ                                                            
237  @nat.lt_of_sub_lt_sub_right _ _ k (by rwa nat.add_sub_cancel)
id    └────────────────────────┘              └────────────────┘
src   └────────────────────────┘           └──┘└────────────────┘
typ   └────────────────────────┘          └──┘└────────────────┘
doc                                        └──┘
txt                                        └──┘
par                                        └──┘
pid                                           
st                                        └─────────────────────┘
238  
239  protected theorem add_lt_of_lt_sub_left (h : m < n - k) : k + m < n :=
id                                                            
src                                                               
typ                                                           
240  by rw add_comm; exact nat.add_lt_of_lt_sub_right h
id         └──────┘        └────────────────────────┘ 
src     └─┘└──────┘  └────┘└────────────────────────┘ 
typ     └─┘└──────┘  └────┘└────────────────────────┘
doc     └─┘          └────┘                           
txt     └─┘          └────┘                           
par     └─┘          └────┘                           
pid                                                 
st     └────────────────────────────────────────────────
241  
src  
typ  
doc  
txt  
par  
pid  
st   
242  protected theorem le_add_of_sub_le_right : n - k ≤ m → n ≤ m + k :=
id                                                         
src                                                            
typ                                                        
243  le_imp_le_of_lt_imp_lt nat.lt_sub_right_of_add_lt
id   └────────────────────┘ └────────────────────────┘
src  └────────────────────┘ └────────────────────────┘
typ  └────────────────────┘ └────────────────────────┘
244  
245  protected theorem le_add_of_sub_le_left : n - k ≤ m → n ≤ k + m :=
id                                                        
src                                                           
typ                                                       
246  le_imp_le_of_lt_imp_lt nat.lt_sub_left_of_add_lt
id   └────────────────────┘ └───────────────────────┘
src  └────────────────────┘ └───────────────────────┘
typ  └────────────────────┘ └───────────────────────┘
247  
248  protected theorem lt_add_of_sub_lt_right : n - k < m → n < m + k :=
id                                                         
src                                                            
typ                                                        
249  lt_imp_lt_of_le_imp_le nat.le_sub_right_of_add_le
id   └────────────────────┘ └────────────────────────┘
src  └────────────────────┘ └────────────────────────┘
typ  └────────────────────┘ └────────────────────────┘
250  
251  protected theorem lt_add_of_sub_lt_left : n - k < m → n < k + m :=
id                                                        
src                                                           
typ                                                       
252  lt_imp_lt_of_le_imp_le nat.le_sub_left_of_add_le
id   └────────────────────┘ └───────────────────────┘
src  └────────────────────┘ └───────────────────────┘
typ  └────────────────────┘ └───────────────────────┘
253  
254  protected theorem sub_le_left_of_le_add : n ≤ k + m → n - k ≤ m :=
id                                                        
src                                                           
typ                                                       
255  le_imp_le_of_lt_imp_lt nat.add_lt_of_lt_sub_left
id   └────────────────────┘ └───────────────────────┘
src  └────────────────────┘ └───────────────────────┘
typ  └────────────────────┘ └───────────────────────┘
256  
257  protected theorem sub_le_right_of_le_add : n ≤ m + k → n - k ≤ m :=
id                                                         
src                                                            
typ                                                        
258  le_imp_le_of_lt_imp_lt nat.add_lt_of_lt_sub_right
id   └────────────────────┘ └────────────────────────┘
src  └────────────────────┘ └────────────────────────┘
typ  └────────────────────┘ └────────────────────────┘
259  
260  protected theorem sub_lt_left_iff_lt_add (H : n ≤ k) : k - n < m ↔ k < n + m :=
id                                                                 
src                                                                      
typ                                                                
261  ⟨nat.lt_add_of_sub_lt_left,
id    └───────────────────────┘
src   └───────────────────────┘
typ   └───────────────────────┘
262   λ h₁,
id      └┘
typ     └┘
263    have succ k ≤ n + m,   from succ_le_of_lt h₁,
id          └──┘              └───────────┘ └┘
src         └──┘                 └───────────┘
typ         └──┘              └───────────┘ └┘
264    have succ (k - n) ≤ m, from
id          └──┘       
src         └──┘        
typ         └──┘       
265      calc succ (k - n) = succ k - n : by rw (succ_sub H)
id            └──┘        └──┘             └──────┘ 
src           └──┘          └──┘           └─┘ └──────┘ └─
typ           └──┘        └──┘         └─┘ └──────┘└─
doc                                          └─┘          └─
txt                                          └─┘          └─
par                                          └─┘          └─
pid                                                      
st                                          └────────────────
266            ...     ≤ n + m - n      : nat.sub_le_sub_right this n
id                                   └──────────────────┘ └──┘ 
src  ─────────┘                         └──────────────────┘
typ  ─────────┘                      └──────────────────┘ └──┘ 
doc  ─────────┘
txt  ─────────┘
par  ─────────┘
pid  ─────────┘
st   ─────────┘
267            ...     = m              : by rw nat.add_sub_cancel_left,
id                                             └─────────────────────┘
src                                          └─┘└─────────────────────┘
typ                                         └─┘└─────────────────────┘
doc                                          └─┘
txt                                          └─┘
par                                          └─┘
pid                                            
st                                          └─────────────────────────┘
268    lt_of_succ_le this⟩
id     └───────────┘ └──┘
src    └───────────┘
typ    └───────────┘ └──┘
269  
270  protected theorem le_sub_left_iff_add_le (H : m ≤ k) : n ≤ k - m ↔ m + n ≤ k :=
id                                                                 
src                                                                      
typ                                                                
271  le_iff_le_iff_lt_iff_lt.2 (nat.sub_lt_left_iff_lt_add H)
id   └─────────────────────┘   └────────────────────────┘ 
src  └─────────────────────┘   └────────────────────────┘
typ  └─────────────────────┘   └────────────────────────┘ 
272  
273  protected theorem le_sub_right_iff_add_le (H : n ≤ k) : m ≤ k - n ↔ m + n ≤ k :=
id                                                                  
src                                                                       
typ                                                                 
274  by rw [nat.le_sub_left_iff_add_le H, add_comm]
id          └────────────────────────┘   └──────┘
src     └──┘└────────────────────────┘ └┘└──────┘└─
typ     └──┘└────────────────────────┘└┘└──────┘└─
doc     └──┘                           └┘        └─
txt     └──┘                           └┘        └─
par     └──┘                           └┘        └─
pid       └┘                           └┘        
st     └───────────────────────────────┘└────────┘
275  
src  
typ  
doc  
txt  
par  
pid  
st   
276  protected theorem lt_sub_left_iff_add_lt : n < k - m ↔ m + n < k :=
id                                                        
src                                                           
typ                                                       
277  ⟨nat.add_lt_of_lt_sub_left, nat.lt_sub_left_of_add_lt⟩
id    └───────────────────────┘  └───────────────────────┘
src   └───────────────────────┘  └───────────────────────┘
typ   └───────────────────────┘  └───────────────────────┘
278  
279  protected theorem lt_sub_right_iff_add_lt : m < k - n ↔ m + n < k :=
id                                                         
src                                                            
typ                                                        
280  by rw [nat.lt_sub_left_iff_add_lt, add_comm]
id          └────────────────────────┘  └──────┘
src     └──┘└────────────────────────┘└┘└──────┘└─
typ     └──┘└────────────────────────┘└┘└──────┘└─
doc     └──┘                          └┘        └─
txt     └──┘                          └┘        └─
par     └──┘                          └┘        └─
pid       └┘                          └┘        
st     └─────────────────────────────┘└────────┘
281  
src  
typ  
doc  
txt  
par  
pid  
st   
282  theorem sub_le_left_iff_le_add : m - n ≤ k ↔ m ≤ n + k :=
id                                              
src                                                 
typ                                             
283  le_iff_le_iff_lt_iff_lt.2 nat.lt_sub_left_iff_add_lt
id   └─────────────────────┘  └────────────────────────┘
src  └─────────────────────┘  └────────────────────────┘
typ  └─────────────────────┘  └────────────────────────┘
284  
285  theorem sub_le_right_iff_le_add : m - k ≤ n ↔ m ≤ n + k :=
id                                               
src                                                  
typ                                              
286  by rw [nat.sub_le_left_iff_le_add, add_comm]
id          └────────────────────────┘  └──────┘
src     └──┘└────────────────────────┘└┘└──────┘└─
typ     └──┘└────────────────────────┘└┘└──────┘└─
doc     └──┘                          └┘        └─
txt     └──┘                          └┘        └─
par     └──┘                          └┘        └─
pid       └┘                          └┘        
st     └─────────────────────────────┘└────────┘
287  
src  
typ  
doc  
txt  
par  
pid  
st   
288  protected theorem sub_lt_right_iff_lt_add (H : k ≤ m) : m - k < n ↔ m < n + k :=
id                                                                  
src                                                                       
typ                                                                 
289  by rw [nat.sub_lt_left_iff_lt_add H, add_comm]
id          └────────────────────────┘   └──────┘
src     └──┘└────────────────────────┘ └┘└──────┘└─
typ     └──┘└────────────────────────┘└┘└──────┘└─
doc     └──┘                           └┘        └─
txt     └──┘                           └┘        └─
par     └──┘                           └┘        └─
pid       └┘                           └┘        
st     └───────────────────────────────┘└────────┘
290  
src  
typ  
doc  
txt  
par  
pid  
st   
291  protected theorem sub_le_sub_left_iff (H : k ≤ m) : m - n ≤ m - k ↔ k ≤ n :=
id                                                              
src                                                                   
typ                                                             
292  ⟨λ h,
id      
typ     
293    have k + (m - k) - n ≤ m - k, by rwa nat.add_sub_cancel' H,
id                               └─────────────────┘ 
src                                └──┘└─────────────────┘
typ                          └──┘└─────────────────┘
doc                                     └──┘                   
txt                                     └──┘                   
par                                     └──┘                   
pid                                                           
st                                     └────────────────────────┘
294    nat.le_of_add_le_add_right (nat.le_add_of_sub_le_left this),
id     └────────────────────────┘  └───────────────────────┘ └──┘
src    └────────────────────────┘  └───────────────────────┘
typ    └────────────────────────┘  └───────────────────────┘ └──┘
295  nat.sub_le_sub_left _⟩
id   └─────────────────┘
src  └─────────────────┘
typ  └─────────────────┘
296  
297  protected theorem sub_lt_sub_right_iff (H : k ≤ m) : m - k < n - k ↔ m < n :=
id                                                               
src                                                                    
typ                                                              
298  lt_iff_lt_of_le_iff_le (nat.sub_le_sub_right_iff _ _ _ H)
id   └────────────────────┘  └──────────────────────┘       
src  └────────────────────┘  └──────────────────────┘
typ  └────────────────────┘  └──────────────────────┘       
299  
300  protected theorem sub_lt_sub_left_iff (H : n ≤ m) : m - n < m - k ↔ k < n :=
id                                                              
src                                                                   
typ                                                             
301  lt_iff_lt_of_le_iff_le (nat.sub_le_sub_left_iff H)
id   └────────────────────┘  └─────────────────────┘ 
src  └────────────────────┘  └─────────────────────┘
typ  └────────────────────┘  └─────────────────────┘ 
302  
303  protected theorem sub_le_iff : m - n ≤ k ↔ m - k ≤ n :=
id                                            
src                                               
typ                                           
304  nat.sub_le_left_iff_le_add.trans nat.sub_le_right_iff_le_add.symm
id   └────────────────────────┘└────┘ └─────────────────────────┘└───┘
src  └────────────────────────┘└────┘ └─────────────────────────┘└───┘
typ  └────────────────────────┘└────┘ └─────────────────────────┘└───┘
305  
306  protected lemma sub_le_self (n m : ℕ) : n - m ≤ n :=
id                                              
src                                              
typ                                             
307  nat.sub_le_left_of_le_add (nat.le_add_left _ _)
id   └───────────────────────┘  └─────────────┘
src  └───────────────────────┘  └─────────────┘
typ  └───────────────────────┘  └─────────────┘
308  
309  protected theorem sub_lt_iff (h₁ : n ≤ m) (h₂ : k ≤ m) : m - n < k ↔ m - k < n :=
id                                                                
src                                                                       
typ                                                               
310  (nat.sub_lt_left_iff_lt_add h₁).trans (nat.sub_lt_right_iff_lt_add h₂).symm
id    └────────────────────────┘ └┘ └───┘   └─────────────────────────┘ └┘ └──┘
src   └────────────────────────┘    └───┘   └─────────────────────────┘    └──┘
typ   └────────────────────────┘ └┘ └───┘   └─────────────────────────┘ └┘ └──┘
311  
312  lemma pred_le_iff {n m : ℕ} : pred n ≤ m ↔ n ≤ succ m :=
id                                └──┘       └──┘ 
src                               └──┘          └──┘
typ                               └──┘       └──┘ 
313  @nat.sub_le_right_iff_le_add n m 1
id    └─────────────────────────┘  
src   └─────────────────────────┘
typ   └─────────────────────────┘  
314  
315  lemma lt_pred_iff {n m : ℕ} : n < pred m ↔ succ n < m :=
id                                  └──┘   └──┘   
src                                  └──┘    └──┘   
typ                                 └──┘   └──┘   
316  @nat.lt_sub_right_iff_add_lt n 1 m
id    └─────────────────────────┘    
src   └─────────────────────────┘
typ   └─────────────────────────┘    
317  
318  protected theorem mul_ne_zero {n m : ℕ} (n0 : n ≠ 0) (m0 : m ≠ 0) : n * m ≠ 0
id                                                                     
src                                                                        
typ                                                                    
319  | nm := (eq_zero_of_mul_eq_zero nm).elim n0 m0
id     └┘     └────────────────────┘    └──┘  └┘ └┘
src           └────────────────────┘    └──┘
typ    └┘     └────────────────────┘    └──┘  └┘ └┘
320  
321  @[simp] protected theorem mul_eq_zero {a b : ℕ} : a * b = 0 ↔ a = 0 ∨ b = 0 :=
id                                                                 
src                                                                    
typ                                                                
doc    └──┘
322  iff.intro eq_zero_of_mul_eq_zero (by simp [or_imp_distrib] {contextual := tt})
id   └───────┘ └────────────────────┘           └────────────┘                 └┘
src  └───────┘ └────────────────────┘     └────┘└────────────┘└┘ └────────────┘└┘
typ  └───────┘ └────────────────────┘     └────┘└────────────┘└┘ └────────────┘└┘
doc                                       └────┘              └┘ └────────────┘  
txt                                       └────┘              └┘ └────────────┘  
par                                       └────┘              └┘ └────────────┘  
pid                                                          └────────────┘  
st                                       └───────────────────────────────────────┘
323  
324  @[simp] protected theorem zero_eq_mul {a b : ℕ} : 0 = a * b ↔ a = 0 ∨ b = 0 :=
id                                                                 
src                                                                    
typ                                                                
doc    └──┘
325  by rw [eq_comm, nat.mul_eq_zero]
id          └─────┘  └─────────────┘
src     └──┘└─────┘└┘└─────────────┘└─
typ     └──┘└─────┘└┘└─────────────┘└─
doc     └──┘       └┘               └─
txt     └──┘       └┘               └─
par     └──┘       └┘               └─
pid       └┘       └┘               
st     └──────────┘└───────────────┘
326  
src  
typ  
doc  
txt  
par  
pid  
st   
327  lemma eq_zero_of_double_le {a : ℕ} (h : 2 * a ≤ a) : a = 0 :=
id                                                    
src                                                      
typ                                                   
328  nat.eq_zero_of_le_zero $
id   └────────────────────┘
src  └────────────────────┘
typ  └────────────────────┘
329    by rwa [two_mul, nat.add_le_to_le_sub, nat.sub_self] at h; refl
id             └─────┘  └──────────────────┘  └──────────┘
src       └───┘└─────┘└┘└──────────────────┘└┘└──────────┘└────┘  └────
typ       └───┘└─────┘└┘└──────────────────┘└┘└──────────┘└────┘  └────
doc       └───┘       └┘                    └┘            └────┘  └────
txt       └───┘       └┘                    └┘            └────┘  └────
par       └───┘       └┘                    └┘            └────┘  └────
pid          └┘       └┘                    └┘            └───┘      
st       └───────────┘└────────────────────┘└────────────┘└───────────
330  
src  
typ  
doc  
txt  
par  
pid  
st   
331  lemma eq_zero_of_mul_le {a b : ℕ} (hb : 2 ≤ b) (h : b * a ≤ a) : a = 0 :=
id                                                             
src                                                                 
typ                                                            
332  eq_zero_of_double_le $ le_trans (nat.mul_le_mul_right _ hb) h
id   └──────────────────┘   └──────┘  └──────────────────┘   └┘  
src  └──────────────────┘   └──────┘  └──────────────────┘
typ  └──────────────────┘   └──────┘  └──────────────────┘   └┘  
333  
334  lemma le_mul_of_pos_left {m n : ℕ} (h : 0 < n) : m ≤ n * m :=
id                                                     
src                                                      
typ                                                    
335  begin
st   └─────
336    conv {to_lhs, rw [← one_mul(m)]},
id                         └─────┘ 
src    └────┘└────┘└┘└────┘└─────┘  └┘
typ    └────┘└────┘└┘└────┘└─────┘ └┘
txt    └────┘└────┘└┘└────┘         └┘
par    └────┘└────┘└┘└────┘         └┘
pid        └─────────────┘         └─┘
st   ───────┘└────┘└────────────────┘ └┘
337    exact mul_le_mul_of_nonneg_right (nat.succ_le_of_lt h) dec_trivial,
id           └────────────────────────┘  └───────────────┘   └─────────┘
src    └────┘└────────────────────────┘ └───────────────┘ └┘└─────────┘
typ    └────┘└────────────────────────┘ └───────────────┘└┘└─────────┘
doc    └────┘                                             └┘└─────────┘
txt    └────┘                                             └┘
par    └────┘                                             └┘
pid                                                      └┘
st   ───────────────────────────────────────────────────────────────────┘└─
338  end
st   ──┘
339  
340  lemma le_mul_of_pos_right {m n : ℕ} (h : 0 < n) : m ≤ m * n :=
id                                                      
src                                                       
typ                                                     
341  begin
st   └─────
342    conv {to_lhs, rw [← mul_one(m)]},
id                         └─────┘ 
src    └────┘└────┘└┘└────┘└─────┘  └┘
typ    └────┘└────┘└┘└────┘└─────┘ └┘
txt    └────┘└────┘└┘└────┘         └┘
par    └────┘└────┘└┘└────┘         └┘
pid        └─────────────┘         └─┘
st   ───────┘└────┘└────────────────┘ └┘
343    exact mul_le_mul_of_nonneg_left (nat.succ_le_of_lt h) dec_trivial,
id           └───────────────────────┘  └───────────────┘   └─────────┘
src    └────┘└───────────────────────┘ └───────────────┘ └┘└─────────┘
typ    └────┘└───────────────────────┘ └───────────────┘└┘└─────────┘
doc    └────┘                                            └┘└─────────┘
txt    └────┘                                            └┘
par    └────┘                                            └┘
pid                                                     └┘
st   ──────────────────────────────────────────────────────────────────┘└─
344  end
st   ──┘
345  
346  theorem two_mul_ne_two_mul_add_one {n m} : 2 * n ≠ 2 * m + 1 :=
id                                                       
src                                                        
typ                                                      
347  mt (congr_arg (%2)) (by rw [add_comm, add_mul_mod_self_left, mul_mod_right]; exact dec_trivial)
id   └┘  └───────┘              └──────┘  └───────────────────┘  └───────────┘         └─────────┘
src  └┘  └───────┘          └──┘└──────┘└┘└───────────────────┘└┘└───────────┘  └────┘└─────────┘
typ  └┘  └───────┘          └──┘└──────┘└┘└───────────────────┘└┘└───────────┘  └────┘└─────────┘
doc                          └──┘        └┘                     └┘               └────┘└─────────┘
txt                          └──┘        └┘                     └┘               └────┘
par                          └──┘        └┘                     └┘               └────┘
pid                            └┘        └┘                     └┘                    
st                          └───────────┘└─────────────────────┘└─────────────┘└─────────────────┘
348  
349  /-- Recursion principle based on `<`. -/
350  @[elab_as_eliminator]
doc    └────────────────┘
351  protected def strong_rec' {p : ℕ → Sort u} (H : ∀ n, (∀ m, m < n → p m) → p n) : ∀ (n : ℕ), p n
id                                                                                    
src                                                                                        
typ                                                                                   
352  | n := H n (λ m hm, strong_rec' m)
id                └┘  └─────────┘ 
typ               └┘  └─────────┘ 
353  
354  attribute [simp] nat.div_self
id                    └──────────┘
src                   └──────────┘
typ                   └──────────┘
doc             └──┘
355  
356  protected lemma div_le_of_le_mul' {m n : ℕ} {k} (h : m ≤ k * n) : m / k ≤ n :=
id                                                                   
src                                                                      
typ                                                                  
357  (eq_zero_or_pos k).elim
id    └────────────┘  └──┘
src   └────────────┘   └──┘
typ   └────────────┘  └──┘
358    (λ k0, by rw [k0, nat.div_zero]; apply zero_le)
id        └┘         └┘  └──────────┘         └─────┘
src              └──┘  └┘└──────────┘  └────┘└─────┘
typ       └┘     └──┘└┘└┘└──────────┘  └────┘└─────┘
doc              └──┘  └┘              └────┘
txt              └──┘  └┘              └────┘
par              └──┘  └┘              └────┘
pid                └┘  └┘                   
st              └─────┘└────────────┘└─────────────┘
359    (λ k0, (decidable.mul_le_mul_left k0).1 $
id        └┘   └───────────────────────┘ └┘ 
src            └───────────────────────┘    
typ       └┘   └───────────────────────┘ └┘ 
360      calc k * (m / k)
id                 
src                 
typ                
361          ≤ m % k + k * (m / k) : le_add_left _ _
id                          └─────────┘
src                              └─────────┘
typ                         └─────────┘
362      ... = m                   : mod_add_div _ _
id                                  └─────────┘
src                                  └─────────┘
typ                                 └─────────┘
363      ... ≤ k * n               : h)
id                                
src              
typ                               
364  
365  protected lemma div_le_self' (m n : ℕ) : m / n ≤ m :=
id                                               
src                                               
typ                                              
366  (eq_zero_or_pos n).elim
id    └────────────┘  └──┘
src   └────────────┘   └──┘
typ   └────────────┘  └──┘
367    (λ n0, by rw [n0, nat.div_zero]; apply zero_le)
id        └┘         └┘  └──────────┘         └─────┘
src              └──┘  └┘└──────────┘  └────┘└─────┘
typ       └┘     └──┘└┘└┘└──────────┘  └────┘└─────┘
doc              └──┘  └┘              └────┘
txt              └──┘  └┘              └────┘
par              └──┘  └┘              └────┘
pid                └┘  └┘                   
st              └─────┘└────────────┘└─────────────┘
368    (λ n0, nat.div_le_of_le_mul' $ calc
id        └┘  └───────────────────┘
src           └───────────────────┘
typ       └┘  └───────────────────┘
369        m = 1 * m : (one_mul _).symm
id                   └─────┘   └──┘
src                    └─────┘   └──┘
typ                  └─────┘   └──┘
370      ... ≤ n * m : mul_le_mul_right _ n0)
id                  └──────────────┘   └┘
src                   └──────────────┘
typ                 └──────────────┘   └┘
371  
372  theorem le_div_iff_mul_le' {x y : ℕ} {k : ℕ} (k0 : 0 < k) : x ≤ y / k ↔ x * k ≤ y :=
id                                                                     
src                                                                         
typ                                                                    
373  begin
st   └─────
374    revert x, refine nat.strong_rec' _ y,
id                      └─────────────┘   
src    └──────┘  └─────┘└─────────────┘└─┘
typ    └──────┘  └─────┘└─────────────┘└─┘
doc    └──────┘  └─────┘└─────────────┘└─┘
txt    └──────┘  └─────┘               └─┘
par    └──────┘  └─────┘               └─┘
pid          └┘                       └─┘
st   ─────────┘└──────────────────────────┘└─
375    clear y, intros y IH x,
src    └─────┘  └───────────┘
typ    └─────┘  └───────────┘
doc    └─────┘  └───────────┘
txt    └─────┘  └───────────┘
par    └─────┘  └───────────┘
pid         └┘        └─────┘
st   ────────┘└─────────────┘└─
376    cases decidable.lt_or_le y k with h h,
id           └────────────────┘  
src    └────┘└────────────────┘  └───────┘
typ    └────┘└────────────────┘└───────┘
doc    └────┘                    └───────┘
txt    └────┘                    └───────┘
par    └────┘                    └───────┘
pid                             └───────┘
st   ──────────────────────────────────────┘└─
377    { rw [div_eq_of_lt h],
id           └──────────┘ 
src      └──┘└──────────┘ 
typ      └──┘└──────────┘
doc      └──┘             
txt      └──┘             
par      └──┘             
pid        └┘             
st   ───┘└────────────────┘└─
378      cases x with x,
id             
src      └────┘ └─────┘
typ      └────┘└─────┘
doc      └────┘ └─────┘
txt      └────┘ └─────┘
par      └────┘ └─────┘
pid            └─────┘
st   ─────────────────┘└─
379      { simp [zero_mul, zero_le] },
id               └──────┘  └─────┘
src        └────┘└──────┘└┘└─────┘└┘
typ        └────┘└──────┘└┘└─────┘└┘
doc        └────┘        └┘       └┘
txt        └────┘        └┘       └┘
par        └────┘        └┘       └┘
pid                    └┘       
st   ─────┘└───────────────────────┘└┘
380      { rw succ_mul,
id            └──────┘
src        └─┘└──────┘
typ        └─┘└──────┘
doc        └─┘
txt        └─┘
par        └─┘
pid          
st   ────────────────┘└─
381        exact iff_of_false (not_succ_le_zero _)
id               └──────────┘  └──────────────┘
src        └────┘└──────────┘ └──────────────┘└───
typ        └────┘└──────────┘ └──────────────┘└───
doc        └────┘                             └───
txt        └────┘                             └───
par        └────┘                             └───
pid                                          └───
st   ──────────────────────────────────────────────
382          (not_le_of_lt $ lt_of_lt_of_le h (le_add_left _ _)) } },
id            └──────────┘   └────────────┘   └─────────┘
src  ───────┘ └──────────┘ └────────────┘  └─────────┘└─────┘
typ  ───────┘ └──────────┘ └────────────┘ └─────────┘└─────┘
doc  ───────┘                                         └─────┘
txt  ───────┘                                         └─────┘
par  ───────┘                                         └─────┘
pid  ───────┘                                         └────┘
st   ───────────────────────────────────────────────────────────┘└──┘
383    { rw [div_eq_sub_div k0 h],
id           └────────────┘ └┘ 
src      └──┘└────────────┘   
typ      └──┘└────────────┘└┘
doc      └──┘                 
txt      └──┘                 
par      └──┘                 
pid        └┘                 
st   ──────────────────────────┘└─
384      cases x with x,
id             
src      └────┘ └─────┘
typ      └────┘└─────┘
doc      └────┘ └─────┘
txt      └────┘ └─────┘
par      └────┘ └─────┘
pid            └─────┘
st   ─────────────────┘└─
385      { simp [zero_mul, zero_le] },
id               └──────┘  └─────┘
src        └────┘└──────┘└┘└─────┘└┘
typ        └────┘└──────┘└┘└─────┘└┘
doc        └────┘        └┘       └┘
txt        └────┘        └┘       └┘
par        └────┘        └┘       └┘
pid                    └┘       
st   ─────┘└───────────────────────┘└┘
386      { rw [← add_one, nat.add_le_add_iff_le_right, succ_mul,
id               └─────┘  └─────────────────────────┘  └──────┘
src        └────┘└─────┘└┘└─────────────────────────┘└┘└──────┘└─
typ        └────┘└─────┘└┘└─────────────────────────┘└┘└──────┘└─
doc        └────┘       └┘                           └┘        └─
txt        └────┘       └┘                           └┘        └─
par        └────┘       └┘                           └┘        └─
pid          └──┘       └┘                           └┘        └─
st   ──────────────────┘└───────────────────────────┘└────────┘└─
387          IH _ (sub_lt_of_pos_le _ _ k0 h), add_le_to_le_sub _ h] } }
id           └┘    └──────────────┘     └┘    └──────────────┘   
src  ───────┘  └─┘ └──────────────┘└───┘   └─┘└──────────────┘└─┘ └┘
typ  ───────┘└┘└─┘ └──────────────┘└───┘└┘└─┘└──────────────┘└─┘└┘
doc  ───────┘  └─┘                 └───┘   └─┘                └─┘ └┘
txt  ───────┘  └─┘                 └───┘   └─┘                └─┘ └┘
par  ───────┘  └─┘                 └───┘   └─┘                └─┘ └┘
pid  ───────┘  └─┘                 └───┘   └─┘                └─┘ 
st   ───────────────────────────────────────┘└────────────────────┘└───
388  end
st   ──┘
389  
390  theorem div_mul_le_self' (m n : ℕ) : m / n * n ≤ m :=
id                                             
src                                              
typ                                            
391  (nat.eq_zero_or_pos n).elim (λ n0, by simp [n0, zero_le]) $ λ n0,
id    └────────────────┘  └──┘     └┘           └┘  └─────┘       └┘
src   └────────────────┘   └──┘            └────┘  └┘└─────┘
typ   └────────────────┘  └──┘     └┘     └────┘└┘└┘└─────┘      └┘
doc                                        └────┘  └┘       
txt                                        └────┘  └┘       
par                                        └────┘  └┘       
pid                                              └┘       
st                                        └─────────────────┘
392  (le_div_iff_mul_le' n0).1 (le_refl _)
id    └────────────────┘ └┘    └─────┘
src   └────────────────┘       └─────┘
typ   └────────────────┘ └┘    └─────┘
393  
394  theorem div_lt_iff_lt_mul' {x y : ℕ} {k : ℕ} (k0 : 0 < k) : x / k < y ↔ x < y * k :=
id                                                                     
src                                                                         
typ                                                                    
395  lt_iff_lt_of_le_iff_le $ le_div_iff_mul_le' k0
id   └────────────────────┘   └────────────────┘ └┘
src  └────────────────────┘   └────────────────┘
typ  └────────────────────┘   └────────────────┘ └┘
396  
397  protected theorem div_le_div_right {n m : ℕ} (h : n ≤ m) {k : ℕ} : n / k ≤ m / k :=
id                                                                       
src                                                                          
typ                                                                      
398  (nat.eq_zero_or_pos k).elim (λ k0, by simp [k0]) $ λ hk,
id    └────────────────┘  └──┘     └┘           └┘       └┘
src   └────────────────┘   └──┘            └────┘  
typ   └────────────────┘  └──┘     └┘     └────┘└┘      └┘
doc                                        └────┘  
txt                                        └────┘  
par                                        └────┘  
pid                                              
st                                        └────────┘
399  (le_div_iff_mul_le' hk).2 $ le_trans (nat.div_mul_le_self' _ _) h
id    └────────────────┘ └┘     └──────┘  └──────────────────┘      
src   └────────────────┘        └──────┘  └──────────────────┘
typ   └────────────────┘ └┘     └──────┘  └──────────────────┘      
400  
401  lemma lt_of_div_lt_div {m n k : ℕ} (h : m / k < n / k) : m < n :=
id                                                      
src                                                         
typ                                                     
402  by_contradiction $ λ h₁, absurd h (not_lt_of_ge (nat.div_le_div_right (not_lt.1 h₁)))
id   └──────────────┘     └┘  └────┘   └──────────┘  └──────────────────┘  └────┘  └┘
src  └──────────────┘         └────┘    └──────────┘  └──────────────────┘  └────┘
typ  └──────────────┘     └┘  └────┘   └──────────┘  └──────────────────┘  └────┘  └┘
403  
404  protected theorem eq_mul_of_div_eq_right {a b c : ℕ} (H1 : b ∣ a) (H2 : a / b = c) :
id                                                                           
src                                                                             
typ                                                                          
405    a = b * c :=
id         
src         
typ        
406  by rw [← H2, nat.mul_div_cancel' H1]
id            └┘  └─────────────────┘ └┘
src     └────┘  └┘└─────────────────┘  └─
typ     └────┘└┘└┘└─────────────────┘└┘└─
doc     └────┘  └┘                     └─
txt     └────┘  └┘                     └─
par     └────┘  └┘                     └─
pid       └──┘  └┘                     
st     └───────┘└──────────────────────┘
407  
src  
typ  
doc  
txt  
par  
pid  
st   
408  protected theorem div_eq_iff_eq_mul_right {a b c : ℕ} (H : 0 < b) (H' : b ∣ a) :
id                                                                          
src                                                                          
typ                                                                         
409    a / b = c ↔ a = b * c :=
id               
src                  
typ              
410  ⟨nat.eq_mul_of_div_eq_right H', nat.div_eq_of_eq_mul_right H⟩
id    └────────────────────────┘ └┘  └────────────────────────┘ 
src   └────────────────────────┘     └────────────────────────┘
typ   └────────────────────────┘ └┘  └────────────────────────┘ 
411  
412  protected theorem div_eq_iff_eq_mul_left {a b c : ℕ} (H : 0 < b) (H' : b ∣ a) :
id                                                                         
src                                                                         
typ                                                                        
413    a / b = c ↔ a = c * b :=
id               
src                  
typ              
414  by rw mul_comm; exact nat.div_eq_iff_eq_mul_right H H'
id         └──────┘        └─────────────────────────┘  └┘
src     └─┘└──────┘  └────┘└─────────────────────────┘   
typ     └─┘└──────┘  └────┘└─────────────────────────┘└┘
doc     └─┘          └────┘                              
txt     └─┘          └────┘                              
par     └─┘          └────┘                              
pid                                                    
st     └────────────────────────────────────────────────────
415  
src  
typ  
doc  
txt  
par  
pid  
st   
416  protected theorem eq_mul_of_div_eq_left {a b c : ℕ} (H1 : b ∣ a) (H2 : a / b = c) :
id                                                                          
src                                                                            
typ                                                                         
417    a = c * b :=
id         
src         
typ        
418  by rw [mul_comm, nat.eq_mul_of_div_eq_right H1 H2]
id          └──────┘  └────────────────────────┘ └┘ └┘
src     └──┘└──────┘└┘└────────────────────────┘    └─
typ     └──┘└──────┘└┘└────────────────────────┘└┘└┘└─
doc     └──┘        └┘                              └─
txt     └──┘        └┘                              └─
par     └──┘        └┘                              └─
pid       └┘        └┘                              
st     └───────────┘└────────────────────────────────┘
419  
src  
typ  
doc  
txt  
par  
pid  
st   
420  protected theorem mul_div_cancel_left' {a b : ℕ} (Hd :  a ∣ b) : a * (b / a) = b :=
id                                                                        
src                                                                           
typ                                                                       
421  by rw [mul_comm,nat.div_mul_cancel Hd]
id          └──────┘ └────────────────┘ └┘
src     └──┘└──────┘└────────────────┘  └─
typ     └──┘└──────┘└────────────────┘└┘└─
doc     └──┘                            └─
txt     └──┘                            └─
par     └──┘                            └─
pid       └┘                            
st     └───────────┘└────────────────────┘
422  
src  
typ  
doc  
txt  
par  
pid  
st   
423  protected theorem div_mod_unique {n k m d : ℕ} (h : 0 < k) :
id                                                         
src                                                       
typ                                                        
424    n / k = d ∧ n % k = m ↔ m + k * d = n ∧ m < k :=
id                           
src                                    
typ                          
425  ⟨λ ⟨e₁, e₂⟩, e₁ ▸ e₂ ▸ ⟨mod_add_div _ _, mod_lt _ h⟩,
id      └┘  └┘            └─────────┘      └────┘   
src                        └─────────┘      └────┘
typ     └┘  └┘            └─────────┘      └────┘   
426   λ ⟨h₁, h₂⟩, h₁ ▸ by rw [add_mul_div_left _ _ h, add_mul_mod_self_left];
id      └┘                  └──────────────┘       └───────────────────┘
src                      └──┘└──────────────┘└───┘ └┘└───────────────────┘
typ     └┘              └──┘└──────────────┘└───┘└┘└───────────────────┘
doc                       └──┘                └───┘ └┘                     
txt                       └──┘                └───┘ └┘                     
par                       └──┘                └───┘ └┘                     
pid                         └┘                └───┘ └┘                     
st                       └─────────────────────────┘└─────────────────────┘└─
427     simp [div_eq_of_lt, mod_eq_of_lt, h₂]⟩
id            └──────────┘  └──────────┘  └┘
src     └────┘└──────────┘└┘└──────────┘└┘  
typ     └────┘└──────────┘└┘└──────────┘└┘└┘
doc     └────┘            └┘            └┘  
txt     └────┘            └┘            └┘  
par     └────┘            └┘            └┘  
pid                     └┘            └┘  
st   ───────────────────────────────────────┘
428  
429  lemma two_mul_odd_div_two {n : ℕ} (hn : n % 2 = 1) : 2 * (n / 2) = n - 1 :=
id                                                               
src                                                                 
typ                                                              
430  by conv {to_rhs, rw [← nat.mod_add_div n 2, hn, nat.add_sub_cancel_left]}
id                          └─────────────┘     └┘  └─────────────────────┘
src     └────┘└────┘└┘└────┘└─────────────┘ └──┘  └┘└─────────────────────┘└─
typ     └────┘└────┘└┘└────┘└─────────────┘└──┘└┘└┘└─────────────────────┘└─
txt     └────┘└────┘└┘└────┘                └──┘  └┘                       └─
par     └────┘└────┘└┘└────┘                └──┘  └┘                       └─
pid         └─────────────┘                └──┘  └┘                       └┘
st     └─────┘└────┘└────────────────────────┘└───┘└───────────────────────┘ 
431  
src  
typ  
txt  
par  
pid  
st   
432  lemma div_dvd_of_dvd {a b : ℕ} (h : b ∣ a) : (a / b) ∣ a :=
id                                                  
src                                                    
typ                                                 
433  ⟨b, (nat.div_mul_cancel h).symm⟩
id       └────────────────┘  └──┘
src       └────────────────┘   └──┘
typ      └────────────────┘  └──┘
434  
435  protected lemma div_pos {a b : ℕ} (hba : b ≤ a) (hb : 0 < b) : 0 < a / b :=
id                                                                 
src                                                                   
typ                                                                
436  nat.pos_of_ne_zero (λ h, lt_irrefl a
id   └────────────────┘      └───────┘ 
src  └────────────────┘       └───────┘
typ  └────────────────┘      └───────┘ 
437    (calc a = a % b : by simpa [h] using (mod_add_div a b).symm
id                                      └─────────┘  
src                        └─────┘ └──────┘ └─────────┘  └──────
typ                     └─────┘└──────┘ └─────────┘└──────
doc                         └─────┘ └──────┘              └──────
txt                         └─────┘ └──────┘              └──────
par                         └─────┘ └──────┘              └──────
pid                               └────┘              └───┘└─
st                         └───────────────────────────────────────
438        ... < b : nat.mod_lt a hb
id                  └────────┘  └┘
src  ─────┘          └────────┘
typ  ─────┘         └────────┘  └┘
doc  ─────┘
txt  ─────┘
par  ─────┘
pid  ─────┘
st   ─────┘
439        ... ≤ a : hba))
id                  └─┘
typ                 └─┘
440  
441  protected theorem mul_right_inj {a b c : ℕ} (ha : 0 < a) : b * a = c * a ↔ b = c :=
id                                                                     
src                                                                         
typ                                                                    
442  ⟨nat.eq_of_mul_eq_mul_right ha, λ e, e ▸ rfl⟩
id    └────────────────────────┘ └┘        └─┘
src   └────────────────────────┘             └─┘
typ   └────────────────────────┘ └┘        └─┘
443  
444  protected theorem mul_left_inj {a b c : ℕ} (ha : 0 < a) : a * b = a * c ↔ b = c :=
id                                                                    
src                                                                        
typ                                                                   
445  ⟨nat.eq_of_mul_eq_mul_left ha, λ e, e ▸ rfl⟩
id    └───────────────────────┘ └┘        └─┘
src   └───────────────────────┘             └─┘
typ   └───────────────────────┘ └┘        └─┘
446  
447  protected lemma div_div_self : ∀ {a b : ℕ}, b ∣ a → 0 < a → a / (a / b) = b
id                                                                
src                                                                     
typ                                                               
448  | a     0     h₁ h₂ := by rw eq_zero_of_zero_dvd h₁; refl
id                                └─────────────────┘ └┘
src                            └─┘└─────────────────┘    └───┘
typ                            └─┘└─────────────────┘└┘  └───┘
doc                            └─┘                       └───┘
txt                            └─┘                       └───┘
par                            └─┘                       └───┘
pid                                                         
st                            └───────────────────────────────┘
449  | 0     b     h₁ h₂ := absurd h₂ dec_trivial
id                    └┘    └────┘    └─────────┘
src                         └────┘    └─────────┘
typ                   └┘    └────┘    └─────────┘
doc                                   └─────────┘
450  | (a+1) (b+1) h₁ h₂ :=
id             └┘
src           
typ            └┘
451  (nat.mul_right_inj (nat.div_pos (le_of_dvd (succ_pos a) h₁) (succ_pos b))).1 $
id    └───────────────┘  └─────────┘  └───────┘  └──────┘         └──────┘     
src   └───────────────┘  └─────────┘  └───────┘  └──────┘         └──────┘     
typ   └───────────────┘  └─────────┘  └───────┘  └──────┘         └──────┘     
452    by rw [nat.div_mul_cancel (div_dvd_of_dvd h₁), nat.mul_div_cancel' h₁]
id            └────────────────┘  └────────────┘ └┘   └─────────────────┘ └┘
src       └──┘└────────────────┘ └────────────┘  └─┘└─────────────────┘  └─
typ       └──┘└────────────────┘ └────────────┘└┘└─┘└─────────────────┘└┘└─
doc       └──┘                                   └─┘                     └─
txt       └──┘                                   └─┘                     └─
par       └──┘                                   └─┘                     └─
pid         └┘                                   └─┘                     
st       └─────────────────────────────────────────┘└──────────────────────┘
453  
src  
typ  
doc  
txt  
par  
pid  
st   
454  protected lemma div_lt_of_lt_mul {m n k : ℕ} (h : m < n * k) : m / n < k :=
id                                                                
src                                                                   
typ                                                               
455  lt_of_mul_lt_mul_left
id   └───────────────────┘
src  └───────────────────┘
typ  └───────────────────┘
456    (calc n * (m / n) ≤ m % n + n * (m / n) : nat.le_add_left _ _
id                                 └─────────────┘
src                                        └─────────────┘
typ                                └─────────────┘
457      ... = m : mod_add_div _ _
id                └─────────┘
src                └─────────┘
typ               └─────────┘
458      ... < n * k : h)
id                  
src              
typ                 
459    (nat.zero_le n)
id      └─────────┘ 
src     └─────────┘
typ     └─────────┘ 
460  
461  lemma lt_mul_of_div_lt {a b c : ℕ} (h : a / c < b) (w : 0 < c) : a < b * c :=
id                                                                
src                                                                    
typ                                                               
462  lt_of_not_ge $ not_le_of_gt h ∘ (nat.le_div_iff_mul_le _ _ w).2
id   └──────────┘   └──────────┘    └───────────────────┘      
src  └──────────┘   └──────────┘     └───────────────────┘       
typ  └──────────┘   └──────────┘    └───────────────────┘      
463  
464  protected lemma div_eq_zero_iff {a b : ℕ} (hb : 0 < b) : a / b = 0 ↔ a < b :=
id                                                                  
src                                                                    
typ                                                                 
465  ⟨λ h, by rw [← mod_add_div a b, h, mul_zero, add_zero]; exact mod_lt _ hb,
id                 └─────────┘      └──────┘  └──────┘         └────┘   └┘
src           └────┘└─────────┘  └┘ └┘└──────┘└┘└──────┘  └────┘└────┘└─┘
typ          └────┘└─────────┘└┘└┘└──────┘└┘└──────┘  └────┘└────┘└─┘└┘
doc           └────┘             └┘ └┘        └┘          └────┘      └─┘
txt           └────┘             └┘ └┘        └┘          └────┘      └─┘
par           └────┘             └┘ └┘        └┘          └────┘      └─┘
pid             └──┘             └┘ └┘        └┘                     └─┘
st           └────────────────────┘└─┘└────────┘└────────┘└─────────────────┘
466    λ h, by rw [← nat.mul_left_inj hb, ← @add_left_cancel_iff _ _ (a % b), mod_add_div,
id                  └──────────────┘ └┘     └─────────────────┘           └─────────┘
src            └────┘└──────────────┘  └──┘ └─────────────────┘└───┘   └─┘└─────────┘└─
typ           └────┘└──────────────┘└┘└──┘ └─────────────────┘└───┘ └─┘└─────────┘└─
doc            └────┘                  └──┘                    └───┘    └─┘           └─
txt            └────┘                  └──┘                    └───┘    └─┘           └─
par            └────┘                  └──┘                    └───┘    └─┘           └─
pid              └──┘                  └──┘                    └───┘    └─┘           └─
st            └────────────────────────┘└──────────────────────────────────┘└───────────┘└─
467      mod_eq_of_lt h, mul_zero, add_zero]⟩
id       └──────────┘   └──────┘  └──────┘
src  ───┘└──────────┘ └┘└──────┘└┘└──────┘
typ  ───┘└──────────┘└┘└──────┘└┘└──────┘
doc  ───┘             └┘        └┘        
txt  ───┘             └┘        └┘        
par  ───┘             └┘        └┘        
pid  ───┘             └┘        └┘        
st   ─────────────────┘└────────┘└────────┘
468  
469  lemma eq_zero_of_le_div {a b : ℕ} (hb : 2 ≤ b) (h : a ≤ a / b) : a = 0 :=
id                                                             
src                                                                 
typ                                                            
470  eq_zero_of_mul_le hb $
id   └───────────────┘ └┘
src  └───────────────┘
typ  └───────────────┘ └┘
471    by rw mul_comm; exact (nat.le_div_iff_mul_le' (lt_of_lt_of_le dec_trivial hb)).1 h
id           └──────┘         └────────────────────┘  └────────────┘ └─────────┘ └┘     
src       └─┘└──────┘  └────┘ └────────────────────┘ └────────────┘└─────────┘  └───┘ 
typ       └─┘└──────┘  └────┘ └────────────────────┘ └────────────┘└─────────┘└┘└───┘
doc       └─┘          └────┘                                      └─────────┘  └───┘ 
txt       └─┘          └────┘                                                   └───┘ 
par       └─┘          └────┘                                                   └───┘ 
pid                                                                           └───┘ 
st       └────────────────────────────────────────────────────────────────────────────────
472  
src  
typ  
doc  
txt  
par  
pid  
st   
473  lemma mul_div_le_mul_div_assoc (a b c : ℕ) : a * (b / c) ≤ (a * b) / c :=
id                                                             
src                                                                
typ                                                            
474  if hc0 : c = 0 then by simp [hc0]
id   └┘                         └─┘
src  └┘                    └────┘   └┘
typ  └┘                   └────┘└─┘└┘
doc                         └────┘   └┘
txt                         └────┘   └┘
par                         └────┘   └┘
pid                                
st                         └──────────┘
475  else (nat.le_div_iff_mul_le _ _ (nat.pos_of_ne_zero hc0)).2
id         └───────────────────┘      └────────────────┘ └─┘  
src        └───────────────────┘      └────────────────┘      
typ        └───────────────────┘      └────────────────┘ └─┘  
476    (by rw [mul_assoc]; exact mul_le_mul_left _ (nat.div_mul_le_self _ _))
id             └───────┘         └─────────────┘    └─────────────────┘
src        └──┘└───────┘  └────┘└─────────────┘└─┘ └─────────────────┘└───┘
typ        └──┘└───────┘  └────┘└─────────────┘└─┘ └─────────────────┘└───┘
doc        └──┘           └────┘               └─┘                    └───┘
txt        └──┘           └────┘               └─┘                    └───┘
par        └──┘           └────┘               └─┘                    └───┘
pid          └┘                               └─┘                    └───┘
st        └────────────┘└─────────────────────────────────────────────────┘
477  
478  lemma div_mul_div_le_div (a b c : ℕ) : ((a / c) * b) / a ≤ b / c :=
id                                                       
src                                                          
typ                                                      
479  if ha0 : a = 0 then by simp [ha0]
id   └┘                         └─┘
src  └┘                    └────┘   └┘
typ  └┘                   └────┘└─┘└┘
doc                         └────┘   └┘
txt                         └────┘   └┘
par                         └────┘   └┘
pid                                
st                         └──────────┘
480  else calc a / c * b / a ≤ b * a / c / a :
id                            
src                                 
typ                           
481      nat.div_le_div_right (by rw [mul_comm];
id       └──────────────────┘         └──────┘
src      └──────────────────┘     └──┘└──────┘
typ      └──────────────────┘     └──┘└──────┘
doc                               └──┘        
txt                               └──┘        
par                               └──┘        
pid                                 └┘        
st                               └───────────┘└─
482          exact mul_div_le_mul_div_assoc _ _ _)
id                 └──────────────────────┘
src          └────┘└──────────────────────┘└────┘
typ          └────┘└──────────────────────┘└────┘
doc          └────┘                        └────┘
txt          └────┘                        └────┘
par          └────┘                        └────┘
pid                                       └────┘
st   ───────────────────────────────────────────┘
483    ... = b / c : by rw [nat.div_div_eq_div_mul, mul_comm b, mul_comm c,
id     └─┘               └────────────────────┘  └──────┘   └──────┘ 
src                    └──┘└────────────────────┘└┘└──────┘ └┘└──────┘ └─
typ    └─┘           └──┘└────────────────────┘└┘└──────┘└┘└──────┘└─
doc                     └──┘                      └┘         └┘         └─
txt                     └──┘                      └┘         └┘         └─
par                     └──┘                      └┘         └┘         └─
pid                       └┘                      └┘         └┘         └─
st                     └─────────────────────────┘└──────────┘└──────────┘└─
484        nat.mul_div_mul _ _ (nat.pos_of_ne_zero ha0)]
id         └─────────────┘      └────────────────┘ └─┘
src  ─────┘└─────────────┘└───┘ └────────────────┘   └──
typ  ─────┘└─────────────┘└───┘ └────────────────┘└─┘└──
doc  ─────┘               └───┘                      └──
txt  ─────┘               └───┘                      └──
par  ─────┘               └───┘                      └──
pid  ─────┘               └───┘                      └┘
st   ─────────────────────────────────────────────────┘
485  
src  
typ  
doc  
txt  
par  
pid  
st   
486  lemma eq_zero_of_le_half {a : ℕ} (h : a ≤ a / 2) : a = 0 :=
id                                                  
src                                                    
typ                                                 
487  eq_zero_of_le_div (le_refl _) h
id   └───────────────┘  └─────┘    
src  └───────────────┘  └─────┘
typ  └───────────────┘  └─────┘    
488  
489  lemma mod_mul_right_div_self (a b c : ℕ) : a % (b * c) / b = (a / b) % c :=
id                                                             
src                                                                 
typ                                                            
490  if hb : b = 0 then by simp [hb] else if hc : c = 0 then by simp [hc]
id   └┘                        └┘       └┘                        └┘
src  └┘                   └────┘  └┘     └┘                   └────┘  └┘
typ  └┘                  └────┘└┘└┘     └┘                  └────┘└┘└┘
doc                        └────┘  └┘                           └────┘  └┘
txt                        └────┘  └┘                           └────┘  └┘
par                        └────┘  └┘                           └────┘  └┘
pid                                                               
st                        └─────────┘                          └─────────┘
491  else by conv {to_rhs, rw ← mod_add_div a (b * c)};
id                              └─────────┘     
src          └────┘└────┘└┘└───┘└─────────┘    
typ          └────┘└────┘└┘└───┘└─────────┘ 
txt          └────┘└────┘└┘└───┘                
par          └────┘└────┘└┘└───┘                
pid              └────────────┘                └┘
st          └─────┘└────┘└──────────────────────────┘└┘
492  rw [mul_assoc, nat.add_mul_div_left _ _ (nat.pos_of_ne_zero hb), add_mul_mod_self_left,
id       └───────┘  └──────────────────┘      └────────────────┘ └┘   └───────────────────┘
src  └──┘└───────┘└┘└──────────────────┘└───┘ └────────────────┘  └─┘└───────────────────┘└─
typ  └──┘└───────┘└┘└──────────────────┘└───┘ └────────────────┘└┘└─┘└───────────────────┘└─
doc  └──┘         └┘                    └───┘                     └─┘                     └─
txt  └──┘         └┘                    └───┘                     └─┘                     └─
par  └──┘         └┘                    └───┘                     └─┘                     └─
pid    └┘         └┘                    └───┘                     └─┘                     └─
st   ───┘└───────┘└────────────────────────────────────────────────┘└─────────────────────┘└─
493    mod_eq_of_lt (nat.div_lt_of_lt_mul (mod_lt _ (mul_pos (nat.pos_of_ne_zero hb) (nat.pos_of_ne_zero hc))))]
id     └──────────┘  └──────────────────┘  └────┘    └─────┘                     └┘   └────────────────┘ └┘
src  ─┘└──────────┘ └──────────────────┘ └────┘└─┘ └─────┘                     └┘ └────────────────┘  └─────
typ  ─┘└──────────┘ └──────────────────┘ └────┘└─┘ └─────┘                   └┘└┘ └────────────────┘└┘└─────
doc  ─┘                                        └─┘                             └┘                     └─────
txt  ─┘                                        └─┘                             └┘                     └─────
par  ─┘                                        └─┘                             └┘                     └─────
pid  ─┘                                        └─┘                             └┘                     └───┘
st   ─────────────────────────────────────────────────────────────────────────────────────────────────────────┘
494  
src  
typ  
doc  
txt  
par  
pid  
st   
495  lemma mod_mul_left_div_self (a b c : ℕ) : a % (c * b) / b = (a / b) % c :=
id                                                            
src                                                                
typ                                                           
496  by rw [mul_comm c, mod_mul_right_div_self]
id          └──────┘   └────────────────────┘
src     └──┘└──────┘ └┘└────────────────────┘└─
typ     └──┘└──────┘└┘└────────────────────┘└─
doc     └──┘         └┘                      └─
txt     └──┘         └┘                      └─
par     └──┘         └┘                      └─
pid       └┘         └┘                      
st     └─────────────┘└──────────────────────┘
497  
src  
typ  
doc  
txt  
par  
pid  
st   
498  /- The `n+1`-st triangle number is `n` more than the `n`-th triangle number -/
src  ──────────────────────────────────────────────────────────────────────────────┘
typ  ──────────────────────────────────────────────────────────────────────────────┘
doc  ──────────────────────────────────────────────────────────────────────────────┘
txt  ──────────────────────────────────────────────────────────────────────────────┘
par  ──────────────────────────────────────────────────────────────────────────────┘
pid  ──────────────────────────────────────────────────────────────────────────────┘
st   ──────────────────────────────────────────────────────────────────────────────┘
499  lemma triangle_succ (n : ℕ) : (n + 1) * ((n + 1) - 1) / 2 = n * (n - 1) / 2 + n :=
id                                                                  
src                                                                    
typ                                                                 
500  begin
st   └─────
501    rw [← add_mul_div_left, mul_comm 2 n, ← mul_add, nat.add_sub_cancel, mul_comm],
id           └──────────────┘  └──────┘       └─────┘  └────────────────┘  └──────┘
src    └────┘└──────────────┘└┘└──────┘└─┘ └──┘└─────┘└┘└────────────────┘└┘└──────┘
typ    └────┘└──────────────┘└┘└──────┘└─┘└──┘└─────┘└┘└────────────────┘└┘└──────┘
doc    └────┘                └┘        └─┘ └──┘       └┘                  └┘        
txt    └────┘                └┘        └─┘ └──┘       └┘                  └┘        
par    └────┘                └┘        └─┘ └──┘       └┘                  └┘        
pid      └──┘                └┘        └─┘ └──┘       └┘                  └┘        
st   ───────────────────────┘└────────────┘└─────────┘└──────────────────┘└────────┘└─
502    cases n; refl, apply zero_lt_succ
id                         └──────────┘
src    └────┘   └──┘  └────┘└──────────┘
typ    └────┘  └──┘  └────┘└──────────┘
doc    └────┘   └──┘  └────┘            
txt    └────┘   └──┘  └────┘            
par    └────┘   └──┘  └────┘            
pid                                   
st   ──────────────┘└───────────────────┘
503  end
st   └─┘
504  
505  @[simp] protected theorem dvd_one {n : ℕ} : n ∣ 1 ↔ n = 1 :=
id                                                    
src                                                     
typ                                                   
doc    └──┘
506  ⟨eq_one_of_dvd_one, λ e, e.symm ▸ dvd_refl _⟩
id    └───────────────┘      └───┘  └──────┘
src   └───────────────┘        └───┘  └──────┘
typ   └───────────────┘      └───┘  └──────┘
507  
508  protected theorem dvd_add_left {k m n : ℕ} (h : k ∣ n) : k ∣ m + n ↔ k ∣ m :=
id                                                                
src                                                                    
typ                                                               
509  (nat.dvd_add_iff_left h).symm
id    └──────────────────┘  └──┘
src   └──────────────────┘   └──┘
typ   └──────────────────┘  └──┘
510  
511  protected theorem dvd_add_right {k m n : ℕ} (h : k ∣ m) : k ∣ m + n ↔ k ∣ n :=
id                                                                 
src                                                                     
typ                                                                
512  (nat.dvd_add_iff_right h).symm
id    └───────────────────┘  └──┘
src   └───────────────────┘   └──┘
typ   └───────────────────┘  └──┘
513  
514  /-- A natural number m divides the sum m + n if and only if m divides b.-/
515  @[simp] protected lemma dvd_add_self_left {m n : ℕ} :
id                                                    
src                                                   
typ                                                   
doc    └──┘
516    m ∣ m + n ↔ m ∣ n :=
id             
src               
typ            
517  nat.dvd_add_right (dvd_refl m)
id   └───────────────┘  └──────┘ 
src  └───────────────┘  └──────┘
typ  └───────────────┘  └──────┘ 
518  
519  /-- A natural number m divides the sum n + m if and only if m divides b.-/
520  @[simp] protected lemma dvd_add_self_right {m n : ℕ} :
id                                                     
src                                                    
typ                                                    
doc    └──┘
521    m ∣ n + m ↔ m ∣ n :=
id             
src               
typ            
522  nat.dvd_add_left (dvd_refl m)
id   └──────────────┘  └──────┘ 
src  └──────────────┘  └──────┘
typ  └──────────────┘  └──────┘ 
523  
524  protected theorem mul_dvd_mul_iff_left {a b c : ℕ} (ha : 0 < a) : a * b ∣ a * c ↔ b ∣ c :=
id                                                                            
src                                                                                
typ                                                                           
525  exists_congr $ λ d, by rw [mul_assoc, nat.mul_left_inj ha]
id   └──────────┘              └───────┘  └──────────────┘ └┘
src  └──────────┘           └──┘└───────┘└┘└──────────────┘  └─
typ  └──────────┘          └──┘└───────┘└┘└──────────────┘└┘└─
doc                         └──┘         └┘                  └─
txt                         └──┘         └┘                  └─
par                         └──┘         └┘                  └─
pid                           └┘         └┘                  
st                         └────────────┘└───────────────────┘
526  
src  
typ  
doc  
txt  
par  
pid  
st   
527  protected theorem mul_dvd_mul_iff_right {a b c : ℕ} (hc : 0 < c) : a * c ∣ b * c ↔ a ∣ b :=
id                                                                             
src                                                                                 
typ                                                                            
528  exists_congr $ λ d, by rw [mul_right_comm, nat.mul_right_inj hc]
id   └──────────┘              └────────────┘  └───────────────┘ └┘
src  └──────────┘           └──┘└────────────┘└┘└───────────────┘  └─
typ  └──────────┘          └──┘└────────────┘└┘└───────────────┘└┘└─
doc                         └──┘              └┘                   └─
txt                         └──┘              └┘                   └─
par                         └──┘              └┘                   └─
pid                           └┘              └┘                   
st                         └─────────────────┘└────────────────────┘
529  
src  
typ  
doc  
txt  
par  
pid  
st   
530  lemma succ_div : ∀ (a b : ℕ), (a + 1) / b =
id                                       
src                                         
typ                                      
531    a / b + if b ∣ a + 1 then 1 else 0
id               
src                  
typ              
532  | a     0     := by simp
src                      └───┘
typ                      └───┘
doc                      └───┘
txt                      └───┘
par                      └───┘
pid                          
st                      └────┘
533  | 0     1     := rfl
id                    └─┘
src                   └─┘
typ                   └─┘
534  | 0     (b+2) := have hb2 : b + 2 > 1, from dec_trivial,
id                                           └─────────┘
src                                           └─────────┘
typ                                          └─────────┘
doc                                              └─────────┘
535    by simp [ne_of_gt hb2, div_eq_of_lt hb2]
id              └──────┘ └─┘  └──────────┘ └─┘
src       └────┘└──────┘   └┘└──────────┘   └┘
typ       └────┘└──────┘└─┘└┘└──────────┘└─┘└┘
doc       └────┘           └┘               └┘
txt       └────┘           └┘               └┘
par       └────┘           └┘               └┘
pid                      └┘               
st       └─────────────────────────────────────┘
536  | (a+1) (b+1) := begin
id            
src           
typ           
st                    └─────
537    rw [nat.div_def], conv_rhs { rw nat.div_def },
id         └─────────┘                 └─────────┘
src    └──┘└─────────┘  └─────────┘└─┘└─────────┘
typ    └──┘└─────────┘  └─────────┘└─┘└─────────┘
doc    └──┘           
txt    └──┘             └─────────┘└─┘           
par    └──┘             └─────────┘└─┘           
pid      └┘                     └───┘           └┘
st   ────────────────┘└───────────┘└──────────────┘└┘
538    by_cases hb_eq_a : b = a + 1,
id                           
src    └───────┘       └─┘  └┘
typ    └───────┘       └─┘└┘
doc    └───────┘       └─┘    └┘
txt    └───────┘       └─┘    └┘
par    └───────┘       └─┘    └┘
pid                   └─┘    
st   ─────────────────────────────┘└─
539    { simp [hb_eq_a, le_refl] },
id             └─────┘  └─────┘
src      └────┘       └┘└─────┘└┘
typ      └────┘└─────┘└┘└─────┘└┘
doc      └────┘       └┘       └┘
txt      └────┘       └┘       └┘
par      └────┘       └┘       └┘
pid                 └┘       
st   ───┘└──────────────────────┘└┘
540    by_cases hb_le_a1 : b ≤ a + 1,
id                           
src    └───────┘        └─┘   └┘
typ    └───────┘        └─┘ └┘
doc    └───────┘        └─┘    └┘
txt    └───────┘        └─┘    └┘
par    └───────┘        └─┘    └┘
pid                    └─┘    
st   ──────────────────────────────┘└─
541    { have hb_le_a : b ≤ a, from le_of_lt_succ (lt_of_le_of_ne hb_le_a1 hb_eq_a),
id                                └───────────┘  └────────────┘ └──────┘ └─────┘
src      └─────────────┘     └───┘└───────────┘ └────────────┘               
typ      └─────────────┘   └───┘└───────────┘ └────────────┘└──────┘└─────┘
doc      └─────────────┘     └───┘                                           
txt      └─────────────┘     └───┘                                           
par      └─────────────┘     └───┘                                           
pid      └──────────┘└─┘     └───┘                                           
st   ───┘└──────────────────┘└────────────────────────────────────────────────────┘└─
542      have h₁ : (0 < b + 1 ∧ b + 1 ≤ a + 1 + 1),
id                                    
src      └────────┘ └┘  └─┘   └─┘   └─┘ └─┘
typ      └────────┘ └┘  └─┘  └─┘  └─┘ └─┘
doc      └────────┘ └┘   └─┘   └─┘   └─┘ └─┘
txt      └────────┘ └┘   └─┘   └─┘   └─┘ └─┘
par      └────────┘ └┘   └─┘   └─┘   └─┘ └─┘
pid      └─────┘└─┘ └┘   └─┘   └─┘   └─┘ └─┘
st   ────────────────────────────────────────────┘└─
543        from ⟨succ_pos _, (add_le_add_iff_right _).2 hb_le_a1⟩,
id               └──────┘     └──────────────────┘      └──────┘
src        └───┘ └──────┘└──┘ └──────────────────┘└────┘        
typ        └───┘ └──────┘└──┘ └──────────────────┘└────┘└──────┘
doc        └───┘         └──┘                     └────┘        
txt        └───┘         └──┘                     └────┘        
par        └───┘         └──┘                     └────┘        
pid        └───┘         └──┘                     └────┘        
st   ───────────────────────────────────────────────────────────┘└─
544      have h₂ : (0 < b + 1 ∧ b + 1 ≤ a + 1),
id                                     
src      └────────┘ └┘   └─┘   └─┘   └─┘
typ      └────────┘ └┘   └─┘  └─┘  └─┘
doc      └────────┘ └┘   └─┘   └─┘   └─┘
txt      └────────┘ └┘   └─┘   └─┘   └─┘
par      └────────┘ └┘   └─┘   └─┘   └─┘
pid      └─────┘└─┘ └┘   └─┘   └─┘   └─┘
st   ────────────────────────────────────────┘└─
545        from ⟨succ_pos _, (add_le_add_iff_right _).2 hb_le_a⟩,
id               └──────┘     └──────────────────┘      └─────┘
src        └───┘ └──────┘└──┘ └──────────────────┘└────┘       
typ        └───┘ └──────┘└──┘ └──────────────────┘└────┘└─────┘
doc        └───┘         └──┘                     └────┘       
txt        └───┘         └──┘                     └────┘       
par        └───┘         └──┘                     └────┘       
pid        └───┘         └──┘                     └────┘       
st   ──────────────────────────────────────────────────────────┘└─
546      have dvd_iff : b + 1 ∣ a - b + 1 ↔  b + 1 ∣ a + 1 + 1,
id                                                
src      └─────────────┘  └─┘   └─┘ └┘  └─┘   └─┘ └┘
typ      └─────────────┘  └─┘   └─┘ └┘ └─┘  └─┘ └┘
doc      └─────────────┘  └─┘     └─┘ └┘  └─┘   └─┘ └┘
txt      └─────────────┘  └─┘     └─┘ └┘  └─┘   └─┘ └┘
par      └─────────────┘  └─┘     └─┘ └┘  └─┘   └─┘ └┘
pid      └──────────┘└─┘  └─┘     └─┘ └┘  └─┘   └─┘ 
st   ────────────────────────────────────────────────────────┘└─
547      { rw [nat.dvd_add_iff_left (dvd_refl (b + 1)),
id             └──────────────────┘  └──────┘  
src        └──┘└──────────────────┘ └──────┘   └─────
typ        └──┘└──────────────────┘ └──────┘  └─────
doc        └──┘                                └─────
txt        └──┘                                └─────
par        └──┘                                └─────
pid          └┘                                └─────
st   ─────┘└─────────────────────────────────────────┘└─
548          ← nat.add_sub_add_right a 1 b, add_comm (_ - _), add_assoc,
id             └───────────────────┘      └──────┘          └───────┘
src  ─────────┘└───────────────────┘ └─┘ └┘└──────┘ └┘ └───┘└───────┘└─
typ  ─────────┘└───────────────────┘└─┘└┘└──────┘ └┘ └───┘└───────┘└─
doc  ─────────┘                      └─┘ └┘         └┘ └───┘         └─
txt  ─────────┘                      └─┘ └┘         └┘ └───┘         └─
par  ─────────┘                      └─┘ └┘         └┘ └───┘         └─
pid  ─────────┘                      └─┘ └┘         └┘ └───┘         └─
st   ────────────────────────────────────┘└────────────────┘└─────────┘└─
549          nat.sub_add_cancel (succ_le_succ hb_le_a)],
id           └────────────────┘  └──────────┘ └─────┘
src  ───────┘└────────────────┘ └──────────┘       └┘
typ  ───────┘└────────────────┘ └──────────┘└─────┘└┘
doc  ───────┘                                      └┘
txt  ───────┘                                      └┘
par  ───────┘                                      └┘
pid  ───────┘                                      └┘
st   ────────────────────────────────────────────────┘└──
550        simp },
src        └───┘
typ        └───┘
doc        └───┘
txt        └───┘
par        └───┘
pid            
st   ──────────┘└┘
551      have wf : a - b < a + 1, from lt_succ_of_le (nat.sub_le_self _ _),
id                                   └───────────┘  └─────────────┘
src      └────────┘      └┘  └───┘└───────────┘ └─────────────┘└───┘
typ      └────────┘    └┘  └───┘└───────────┘ └─────────────┘└───┘
doc      └────────┘      └┘  └───┘                             └───┘
txt      └────────┘      └┘  └───┘                             └───┘
par      └────────┘      └┘  └───┘                             └───┘
pid      └─────┘└─┘        └───┘                             └───┘
st   ──────────────────────────┘└────────────────────────────────────────┘└─
552      rw [if_pos h₁, if_pos h₂, nat.add_sub_add_right, nat.sub_add_comm hb_le_a,
id           └────┘ └┘  └────┘ └┘  └───────────────────┘  └──────────────┘ └─────┘
src      └──┘└────┘  └┘└────┘  └┘└───────────────────┘└┘└──────────────┘       └─
typ      └──┘└────┘└┘└┘└────┘└┘└┘└───────────────────┘└┘└──────────────┘└─────┘└─
doc      └──┘        └┘        └┘                     └┘                       └─
txt      └──┘        └┘        └┘                     └┘                       └─
par      └──┘        └┘        └┘                     └┘                       └─
pid        └┘        └┘        └┘                     └┘                       └─
st   ────────────────┘└─────────┘└─────────────────────┘└────────────────────────┘└─
553        by exact have _ := wf, succ_div (a - b),
id                            └┘  └──────┘     
src  ─────┘  └────┘    └────┘  └┘            └─
typ  ─────┘  └────┘    └────┘└┘└┘└──────┘  └─
doc  ─────┘  └────┘    └────┘  └┘            └─
txt  ─────┘  └────┘    └────┘  └┘            └─
par  ─────┘  └────┘    └────┘  └┘            └─
pid  ─────┘  └─────┘    └────┘  └┘            └──
st   ───────┘└───────────────────────────────────┘└─
554        nat.add_sub_add_right],
id         └───────────────────┘
src  ─────┘└───────────────────┘
typ  ─────┘└───────────────────┘
doc  ─────┘                     
txt  ─────┘                     
par  ─────┘                     
pid  ─────┘                     
st   ──────────────────────────┘└──
555      simp [dvd_iff, succ_eq_add_one], congr },
id             └─────┘  └─────────────┘
src      └────┘       └┘└─────────────┘  └────┘
typ      └────┘└─────┘└┘└─────────────┘  └────┘
doc      └────┘       └┘               
txt      └────┘       └┘                 └────┘
par      └────┘       └┘                 └────┘
pid                 └┘                      
st   ──────────────────────────────────┘└──────┘└┘
556    { have hba : ¬ b ≤ a,
id                       
src      └─────────┘   
typ      └─────────┘  
doc      └─────────┘   
txt      └─────────┘   
par      └─────────┘   
pid      └──────┘└─┘   
st   ─────────────────────┘└─
557        from not_le_of_gt (lt_trans (lt_succ_self a) (lt_of_not_ge hb_le_a1)),
id              └──────────┘  └──────┘  └──────────┘    └──────────┘ └──────┘
src        └───┘└──────────┘ └──────┘ └──────────┘ └┘ └──────────┘        └┘
typ        └───┘└──────────┘ └──────┘ └──────────┘└┘ └──────────┘└──────┘└┘
doc        └───┘                                   └┘                     └┘
txt        └───┘                                   └┘                     └┘
par        └───┘                                   └┘                     └┘
pid        └───┘                                   └┘                     └┘
st   ──────────────────────────────────────────────────────────────────────────┘└─
558      have hb_dvd_a : ¬ b + 1 ∣ a + 2,
id                                
src      └──────────────┘   └─┘   └┘
typ      └──────────────┘  └─┘  └┘
doc      └──────────────┘   └─┘   └┘
txt      └──────────────┘   └─┘   └┘
par      └──────────────┘   └─┘   └┘
pid      └───────────┘└─┘   └─┘   
st   ──────────────────────────────────┘└─
559        from λ h, hb_le_a1 (le_of_succ_le_succ (le_of_dvd (succ_pos _) h)),
id                   └──────┘  └────────────────┘  └───────┘  └──────┘
src        └───┘ └──┘         └────────────────┘ └───────┘ └──────┘└──┘ └┘
typ        └───┘ └──┘└──────┘ └────────────────┘ └───────┘ └──────┘└──┘ └┘
doc        └───┘ └──┘                                              └──┘ └┘
txt        └───┘ └──┘                                              └──┘ └┘
par        └───┘ └──┘                                              └──┘ └┘
pid        └───┘ └──┘                                              └──┘ └┘
st   ───────────────────────────────────────────────────────────────────────┘└─
560      simp [hba, hb_le_a1, hb_dvd_a], }
id             └─┘  └──────┘  └──────┘
src      └────┘   └┘        └┘        
typ      └────┘└─┘└┘└──────┘└┘└──────┘
doc      └────┘   └┘        └┘        
txt      └────┘   └┘        └┘        
par      └────┘   └┘        └┘        
pid             └┘        └┘        
st   ─────────────────────────────────┘└───
561  end
st   ──┘
562  
563  lemma succ_div_of_dvd {a b : ℕ} (hba : b ∣ a + 1) :
id                                            
src                                             
typ                                           
564    (a + 1) / b = a / b + 1 :=
id                 
src                    
typ                
565  by rw [succ_div, if_pos hba]
id          └──────┘  └────┘ └─┘
src     └──┘└──────┘└┘└────┘   └─
typ     └──┘└──────┘└┘└────┘└─┘└─
doc     └──┘        └┘         └─
txt     └──┘        └┘         └─
par     └──┘        └┘         └─
pid       └┘        └┘         
st     └───────────┘└──────────┘
566  
src  
typ  
doc  
txt  
par  
pid  
st   
567  lemma succ_div_of_not_dvd {a b : ℕ} (hba : ¬ b ∣ a + 1) :
id                                                 
src                                                  
typ                                                
568    (a + 1) / b = a / b :=
id                
src                 
typ               
569  by rw [succ_div, if_neg hba, add_zero]
id          └──────┘  └────┘ └─┘  └──────┘
src     └──┘└──────┘└┘└────┘   └┘└──────┘└─
typ     └──┘└──────┘└┘└────┘└─┘└┘└──────┘└─
doc     └──┘        └┘         └┘        └─
txt     └──┘        └┘         └┘        └─
par     └──┘        └┘         └┘        └─
pid       └┘        └┘         └┘        
st     └───────────┘└──────────┘└────────┘
570  
src  
typ  
doc  
txt  
par  
pid  
st   
571  @[simp] theorem mod_mod (a n : ℕ) : (a % n) % n = a % n :=
id                                                
src                                                  
typ                                               
doc    └──┘
572  (eq_zero_or_pos n).elim
id    └────────────┘  └──┘
src   └────────────┘   └──┘
typ   └────────────┘  └──┘
573    (λ n0, by simp [n0])
id        └┘           └┘
src              └────┘  
typ       └┘     └────┘└┘
doc              └────┘  
txt              └────┘  
par              └────┘  
pid                    
st              └────────┘
574    (λ npos, mod_eq_of_lt (mod_lt _ npos))
id        └──┘  └──────────┘  └────┘   └──┘
src             └──────────┘  └────┘
typ       └──┘  └──────────┘  └────┘   └──┘
575  
576  @[simp] theorem mod_mod_of_dvd (n : nat) {m k : nat} (h : m ∣ k) : n % k % m = n % m :=
id                                       └─┘         └─┘                     
src                                      └─┘         └─┘                          
typ                                      └─┘         └─┘                     
doc    └──┘
577  begin
st   └─────
578    conv { to_rhs, rw ←mod_add_div n k },
id                        └─────────┘  
src    └─────┘└────┘└┘└──┘└─────────┘  
typ    └─────┘└────┘└┘└──┘└─────────┘
txt    └─────┘└────┘└┘└──┘             
par    └─────┘└────┘└┘└──┘             
pid        └────────────┘             └┘
st   ───────┘└─────┘└────────────────────┘└┘
579    rcases h with ⟨t, rfl⟩, rw [mul_assoc, add_mul_mod_self_left]
id                                └───────┘  └───────────────────┘
src    └─────┘ └────────────┘  └──┘└───────┘└┘└───────────────────┘└┘
typ    └─────┘└────────────┘  └──┘└───────┘└┘└───────────────────┘└┘
doc    └─────┘ └────────────┘  └──┘         └┘                     └┘
txt    └─────┘ └────────────┘  └──┘         └┘                     └┘
par    └─────┘ └────────────┘  └──┘         └┘                     └┘
pid           └────────────┘    └┘         └┘                     
st   ───────────────────────┘└─────────────┘└─────────────────────┘
580  end
st   └─┘
581  
582  theorem add_pos_left {m : ℕ} (h : 0 < m) (n : ℕ) : 0 < m + n :=
id                                                       
src                                                       
typ                                                      
583  calc
584    m + n > 0 + n : nat.add_lt_add_right h n
id                └──────────────────┘  
src                  └──────────────────┘
typ               └──────────────────┘  
585      ... = n     : nat.zero_add n
id                    └──────────┘ 
src                    └──────────┘
typ                   └──────────┘ 
586      ... ≥ 0     : zero_le n
id                     └─────┘ 
src                    └─────┘
typ                    └─────┘ 
587  
588  theorem add_pos_right (m : ℕ) {n : ℕ} (h : 0 < n) : 0 < m + n :=
id                                                        
src                                                        
typ                                                       
589  begin rw add_comm, exact add_pos_left h m end
id            └──────┘        └──────────┘  
src        └─┘└──────┘  └────┘└──────────┘  
typ        └─┘└──────┘  └────┘└──────────┘
doc        └─┘          └────┘              
txt        └─┘          └────┘              
par        └─┘          └────┘              
pid                                       
st   └───────────────┘└───────────────────────┘└─┘
590  
591  theorem add_pos_iff_pos_or_pos (m n : ℕ) : 0 < m + n ↔ 0 < m ∨ 0 < n :=
id                                                            
src                                                             
typ                                                           
592  iff.intro
id   └───────┘
src  └───────┘
typ  └───────┘
593    begin
st     └─────
594      intro h,
src      └─────┘
typ      └─────┘
doc      └─────┘
txt      └─────┘
par      └─────┘
pid           └┘
st   ──────────┘└─
595      cases m with m,
id             
src      └────┘ └─────┘
typ      └────┘└─────┘
doc      └────┘ └─────┘
txt      └────┘ └─────┘
par      └────┘ └─────┘
pid            └─────┘
st   ─────────────────┘└─
596      {simp [zero_add] at h, exact or.inr h},
id              └──────┘              └────┘ 
src       └────┘└──────┘└────┘  └────┘└────┘
typ       └────┘└──────┘└────┘  └────┘└────┘
doc       └────┘        └────┘  └────┘      
txt       └────┘        └────┘  └────┘      
par       └────┘        └────┘  └────┘      
pid                   └──┘             
st   ────────────────────────┘└──────────────┘└┘
597      exact or.inl (succ_pos _)
id             └────┘  └──────┘
src      └────┘└────┘ └──────┘└───
typ      └────┘└────┘ └──────┘└───
doc      └────┘               └───
txt      └────┘               └───
par      └────┘               └───
pid                          └─┘
st   ──────────────────────────────
598    end
src  ─┘
typ  ─┘
doc  ─┘
txt  ─┘
par  ─┘
pid  ─┘
st   ─┘└─┘
599    begin
st     └─────
600      intro h, cases h with mpos npos,
id                      
src      └─────┘  └────┘ └─────────────┘
typ      └─────┘  └────┘└─────────────┘
doc      └─────┘  └────┘ └─────────────┘
txt      └─────┘  └────┘ └─────────────┘
par      └─────┘  └────┘ └─────────────┘
pid           └┘        └─────────────┘
st   ──────────┘└──────────────────────┘└─
601      { apply add_pos_left mpos },
id               └──────────┘ └──┘
src        └────┘└──────────┘    
typ        └────┘└──────────┘└──┘
doc        └────┘                
txt        └────┘                
par        └────┘                
pid                             
st   ─────┘└──────────────────────┘└┘
602      apply add_pos_right _ npos
id             └───────────┘   └──┘
src      └────┘└───────────┘└─┘    
typ      └────┘└───────────┘└─┘└──┘
doc      └────┘             └─┘    
txt      └────┘             └─┘    
par      └────┘             └─┘    
pid                        └─┘    
st   ───────────────────────────────
603    end
src  ─┘
typ  ─┘
doc  ─┘
txt  ─┘
par  ─┘
pid  ─┘
st   ─┘└─┘
604  
605  lemma add_eq_one_iff : ∀ {a b : ℕ}, a + b = 1 ↔ (a = 0 ∧ b = 1) ∨ (a = 1 ∧ b = 0)
id                                                               
src                                                                     
typ                                                              
606  | 0     0     := dec_trivial
id                    └─────────┘
src                   └─────────┘
typ                   └─────────┘
doc                   └─────────┘
607  | 0     1     := dec_trivial
id                    └─────────┘
src                   └─────────┘
typ                   └─────────┘
doc                   └─────────┘
608  | 1     0     := dec_trivial
id                    └─────────┘
src                   └─────────┘
typ                   └─────────┘
doc                   └─────────┘
609  | 1     1     := dec_trivial
id                    └─────────┘
src                   └─────────┘
typ                   └─────────┘
doc                   └─────────┘
610  | (a+2) _     := by rw add_right_comm; exact dec_trivial
id                         └────────────┘        └─────────┘
src                     └─┘└────────────┘  └────┘└─────────┘
typ                     └─┘└────────────┘  └────┘└─────────┘
doc                      └─┘                └────┘           
txt                      └─┘                └────┘           
par                      └─┘                └────┘           
pid                                                        
st                      └────────────────────────────────────┘
611  | _     (b+2) := by rw [← add_assoc]; simp only [nat.succ_inj', nat.succ_ne_zero]; simp
id                            └───────┘              └───────────┘  └──────────────┘
src                     └────┘└───────┘  └─────────┘└───────────┘└┘└──────────────┘  └────
typ                     └────┘└───────┘  └─────────┘└───────────┘└┘└──────────────┘  └────
doc                      └────┘           └─────────┘             └┘                  └────
txt                      └────┘           └─────────┘             └┘                  └────
par                      └────┘           └─────────┘             └┘                  └────
pid                        └──┘               └──┘└┘             └┘                      
st                      └──────────────┘└───────────────────────────────────────────────────
612  
src  
typ  
doc  
txt  
par  
pid  
st   
613  lemma mul_eq_one_iff : ∀ {a b : ℕ}, a * b = 1 ↔ a = 1 ∧ b = 1
id                                                  
src                                                      
typ                                                 
614  | 0     0     := dec_trivial
id                    └─────────┘
src                   └─────────┘
typ                   └─────────┘
doc                   └─────────┘
615  | 0     1     := dec_trivial
id                    └─────────┘
src                   └─────────┘
typ                   └─────────┘
doc                   └─────────┘
616  | 1     0     := dec_trivial
id                    └─────────┘
src                   └─────────┘
typ                   └─────────┘
doc                   └─────────┘
617  | (a+2) 0     := by simp
id       
src                     └───┘
typ                     └───┘
doc                      └───┘
txt                      └───┘
par                      └───┘
pid                          
st                      └────┘
618  | 0     (b+2) := by simp
id             
src                     └───┘
typ                     └───┘
doc                      └───┘
txt                      └───┘
par                      └───┘
pid                          
st                      └────┘
619  | (a+1) (b+1) := ⟨λ h, by simp only [add_mul, mul_add, mul_add, one_mul, mul_one,
id                                     └─────┘  └─────┘  └─────┘  └─────┘  └─────┘
src                          └─────────┘└─────┘└┘└─────┘└┘└─────┘└┘└─────┘└┘└─────┘└─
typ                         └─────────┘└─────┘└┘└─────┘└┘└─────┘└┘└─────┘└┘└─────┘└─
doc                            └─────────┘       └┘       └┘       └┘       └┘       └─
txt                            └─────────┘       └┘       └┘       └┘       └┘       └─
par                            └─────────┘       └┘       └┘       └┘       └┘       └─
pid                                └──┘└┘       └┘       └┘       └┘       └┘       └─
st                            └────────────────────────────────────────────────────────
620      (add_assoc _ _ _).symm, nat.succ_inj', add_eq_zero_iff] at h; simp [h.1.2, h.2],
id        └───────┘              └───────────┘  └─────────────┘                    
src  ───┘ └───────┘└────────────┘└───────────┘└┘└─────────────┘└────┘  └────┘ └────┘ └─┘
typ  ───┘ └───────┘└────────────┘└───────────┘└┘└─────────────┘└────┘  └────┘└────┘└─┘
doc  ───┘          └────────────┘             └┘               └────┘  └────┘ └────┘ └─┘
txt  ───┘          └────────────┘             └┘               └────┘  └────┘ └────┘ └─┘
par  ───┘          └────────────┘             └┘               └────┘  └────┘ └────┘ └─┘
pid  ───┘          └────────────┘             └┘               └──┘       └────┘ └─┘
st   ──────────────────────────────────────────────────────────────────────────────────┘
621    by clear_aux_decl; finish⟩
src       └────────────┘  └────┘
typ       └────────────┘  └────┘
doc       └────────────┘  └────┘
txt       └────────────┘  └────┘
par       └────────────┘  └────┘
st       └─────────────────────┘
622  
623  lemma mul_right_eq_self_iff {a b : ℕ} (ha : 0 < a) : a * b = a ↔ b = 1 :=
id                                                            
src                                                                
typ                                                           
624  suffices a * b = a * 1 ↔ b = 1, by rwa mul_one at this,
id                                 └─────┘
src                                └──┘└─────┘└──────┘
typ                            └──┘└─────┘└──────┘
doc                                     └──┘       └──────┘
txt                                     └──┘       └──────┘
par                                     └──┘       └──────┘
pid                                               └──────┘
st                                     └──────────────────┘
625  nat.mul_left_inj ha
id   └──────────────┘ └┘
src  └──────────────┘
typ  └──────────────┘ └┘
626  
627  lemma mul_left_eq_self_iff {a b : ℕ} (hb : 0 < b) : a * b = b ↔ a = 1 :=
id                                                           
src                                                               
typ                                                          
628  by rw [mul_comm, nat.mul_right_eq_self_iff hb]
id          └──────┘  └───────────────────────┘ └┘
src     └──┘└──────┘└┘└───────────────────────┘  └─
typ     └──┘└──────┘└┘└───────────────────────┘└┘└─
doc     └──┘        └┘                           └─
txt     └──┘        └┘                           └─
par     └──┘        └┘                           └─
pid       └┘        └┘                           
st     └───────────┘└────────────────────────────┘
629  
src  
typ  
doc  
txt  
par  
pid  
st   
630  lemma lt_succ_iff_lt_or_eq {n i : ℕ} : n < i.succ ↔ (n < i ∨ n = i) :=
id                                           └───┘         
src                                            └───┘           
typ                                          └───┘         
631  lt_succ_iff.trans le_iff_lt_or_eq
id   └─────────┘└────┘ └─────────────┘
src  └─────────┘└────┘ └─────────────┘
typ  └─────────┘└────┘ └─────────────┘
632  
633  theorem le_zero_iff {i : ℕ} : i ≤ 0 ↔ i = 0 :=
id                                      
src                                       
typ                                     
634  ⟨nat.eq_zero_of_le_zero, assume h, h ▸ le_refl i⟩
id    └────────────────────┘             └─────┘ 
src   └────────────────────┘               └─────┘
typ   └────────────────────┘             └─────┘ 
635  
636  theorem le_add_one_iff {i j : ℕ} : i ≤ j + 1 ↔ (i ≤ j ∨ i = j + 1) :=
id                                                    
src                                                         
typ                                                   
637  ⟨assume h,
id           
typ          
638    match nat.eq_or_lt_of_le h with
id           └────────────────┘ 
src          └────────────────┘
typ          └────────────────┘ 
639    | or.inl h := or.inr h
id       └────┘     └────┘
src      └────┘      └────┘
typ      └────┘     └────┘
640    | or.inr h := or.inl $ nat.le_of_succ_le_succ h
id       └────┘     └────┘   └────────────────────┘
src      └────┘      └────┘   └────────────────────┘
typ      └────┘     └────┘   └────────────────────┘
641    end,
642    or.rec (assume h, le_trans h $ nat.le_add_right _ _) le_of_eq⟩
id     └────┘           └──────┘    └──────────────┘      └──────┘
src    └────┘            └──────┘     └──────────────┘      └──────┘
typ    └────┘           └──────┘    └──────────────┘      └──────┘
643  
644  theorem mul_self_inj {n m : ℕ} : n * n = m * m ↔ n = m :=
id                                             
src                                                
typ                                            
645  le_antisymm_iff.trans (le_antisymm_iff.trans
id   └─────────────┘└────┘  └─────────────┘└────┘
src  └─────────────┘└────┘  └─────────────┘└────┘
typ  └─────────────┘└────┘  └─────────────┘└────┘
646    (and_congr mul_self_le_mul_self_iff mul_self_le_mul_self_iff)).symm
id      └───────┘ └──────────────────────┘ └──────────────────────┘  └──┘
src     └───────┘ └──────────────────────┘ └──────────────────────┘  └──┘
typ     └───────┘ └──────────────────────┘ └──────────────────────┘  └──┘
647  
648  instance decidable_ball_lt (n : nat) (P : Π k < n, Prop) :
id                                   └─┘            
src                                  └─┘         
typ                                  └─┘            
649    ∀ [H : ∀ n h, decidable (P n h)], decidable (∀ n h, P n h) :=
id                 └───────┘        └───────┘         
src                  └───────┘           └───────┘
typ                └───────┘        └───────┘         
650  begin
st   └─────
651    induction n with n IH; intro; resetI,
id               
src    └────────┘ └────────┘  └───┘  └────┘
typ    └────────┘└────────┘  └───┘  └────┘
doc    └────────┘ └────────┘  └───┘  └────┘
txt    └────────┘ └────────┘  └───┘  └────┘
par    └────────┘ └────────┘  └───┘  └────┘
pid              └───────┘
st   ─────────────────────────────────────┘└─
652    { exact is_true (λ n, dec_trivial) },
id             └─────┘       └─────────┘
src      └────┘└─────┘  └──┘└─────────┘└┘
typ      └────┘└─────┘  └──┘└─────────┘└┘
doc      └────┘         └──┘└─────────┘└┘
txt      └────┘         └──┘           └┘
par      └────┘         └──┘           └┘
pid                    └──┘           
st   ───┘└───────────────────────────────┘└┘
653    cases IH (λ k h, P k (lt_succ_of_lt h)) with h,
id           └┘             └───────────┘
src    └────┘    └────┘   └───────────┘ └───────┘
typ    └────┘└┘  └────┘  └───────────┘ └───────┘
doc    └────┘    └────┘                 └───────┘
txt    └────┘    └────┘                 └───────┘
par    └────┘    └────┘                 └───────┘
pid             └────┘                 └┘└─────┘
st   ───────────────────────────────────────────────┘└─
654    { refine is_false (mt _ h), intros hn k h, apply hn },
id              └──────┘  └┘   
src      └─────┘└──────┘ └┘└─┘   └───────────┘  └────┘  
typ      └─────┘└──────┘ └┘└─┘  └───────────┘  └────┘  
doc      └─────┘           └─┘   └───────────┘  └────┘  
txt      └─────┘           └─┘   └───────────┘  └────┘  
par      └─────┘           └─┘   └───────────┘  └────┘  
pid                       └─┘         └─────┘         
st   ───┘└──────────────────────┘└─────────────┘└─────────┘└┘
655    by_cases p : P n (lt_succ_self n),
id                      └──────────┘ 
src    └───────┘ └─┘   └──────────┘ 
typ    └───────┘ └─┘  └──────────┘
doc    └───────┘ └─┘                
txt    └───────┘ └─┘                
par    └───────┘ └─┘                
pid             └─┘                
st   ──────────────────────────────────┘└─
656    { exact is_true (λ k h',
id             └─────┘
src      └────┘└─────┘  └──────
typ      └────┘└─────┘  └──────
doc      └────┘         └──────
txt      └────┘         └──────
par      └────┘         └──────
pid                    └──────
st   ───┘└──────────────────────
657       (lt_or_eq_of_le $ le_of_lt_succ h').elim (h _)
id         └────────────┘   └───────────┘           
src  ────┘ └────────────┘ └───────────┘  └─────┘  └───
typ  ────┘ └────────────┘ └───────────┘  └─────┘ └───
doc  ────┘                               └─────┘  └───
txt  ────┘                               └─────┘  └───
par  ────┘                               └─────┘  └───
pid  ────┘                               └─────┘  └───
st   ────────────────────────────────────────────────────
658         (λ e, match k, e, h' with _, rfl, h := p end)) },
id                                       └─┘       
src  ──────┘  └──┘      └┘ └┘  └───────┘└─┘└┘ └──┘ └─────┘
typ  ──────┘  └──┘      └┘ └┘  └───────┘└─┘└┘ └──┘└─────┘
doc  ──────┘  └──┘      └┘ └┘  └───────┘   └┘ └──┘ └─────┘
txt  ──────┘  └──┘      └┘ └┘  └───────┘   └┘ └──┘ └─────┘
par  ──────┘  └──┘      └┘ └┘  └───────┘   └┘ └──┘ └─────┘
pid  ──────┘  └──┘      └┘ └┘  └───────┘   └┘ └──┘ └────┘
st   ─────────────────────────────────────────────────────┘└┘
659    { exact is_false (mt (λ hn, hn _ _) p) }
id             └──────┘  └┘                
src      └────┘└──────┘ └┘  └───┘  └────┘ └┘
typ      └────┘└──────┘ └┘  └───┘  └────┘└┘
doc      └────┘             └───┘  └────┘ └┘
txt      └────┘             └───┘  └────┘ └┘
par      └────┘             └───┘  └────┘ └┘
pid                        └───┘  └────┘ 
st   ────────────────────────────────────────┘└─
660  end
st   ──┘
661  
662  instance decidable_forall_fin {n : ℕ} (P : fin n → Prop)
id                                             └─┘ 
src                                            └─┘
typ                                            └─┘ 
663    [H : decidable_pred P] : decidable (∀ i, P i) :=
id          └────────────┘     └───────┘       
src         └────────────┘      └───────┘
typ         └────────────┘     └───────┘       
664  decidable_of_iff (∀ k h, P ⟨k, h⟩) ⟨λ a ⟨k, h⟩, a k h, λ a k h, a ⟨k, h⟩⟩
id   └──────────────┘                                       
src  └──────────────┘
typ  └──────────────┘                                       
665  
666  instance decidable_ball_le (n : ℕ) (P : Π k ≤ n, Prop)
id                                               
src                                           
typ                                              
667    [H : ∀ n h, decidable (P n h)] : decidable (∀ n h, P n h) :=
id               └───────┘         └───────┘         
src                └───────┘            └───────┘
typ              └───────┘         └───────┘         
668  decidable_of_iff (∀ k (h : k < succ n), P k (le_of_lt_succ h))
id   └──────────────┘            └──┘       └───────────┘ 
src  └──────────────┘              └──┘          └───────────┘
typ  └──────────────┘            └──┘       └───────────┘ 
669  ⟨λ a k h, a k (lt_succ_of_le h), λ a k h, a k _⟩
id             └───────────┘           
src                 └───────────┘
typ            └───────────┘           
670  
671  instance decidable_lo_hi (lo hi : ℕ) (P : ℕ → Prop) [H : decidable_pred P] : decidable (∀x, lo ≤ x → x < hi → P x) :=
id                                                          └────────────┘     └───────┘     └┘       └┘    
src                                                         └────────────┘      └───────┘                
typ                                                         └────────────┘     └───────┘     └┘       └┘    
672  decidable_of_iff (∀ x < hi - lo, P (lo + x))
id   └──────────────┘       └┘  └┘    └┘  
src  └──────────────┘                      
typ  └──────────────┘       └┘  └┘    └┘  
673  ⟨λal x hl hh, by have := al (x - lo) (lt_of_not_ge $
id     └┘  └┘ └┘             └┘    └┘   └──────────┘
src                   └──────┘      └┘ └──────────┘ 
typ    └┘  └┘ └┘     └──────┘└┘ └┘└┘ └──────────┘ 
doc                   └──────┘       └┘              
txt                   └──────┘       └┘              
par                   └──────┘       └┘              
pid                   └───┘└─┘       └┘              
st                   └────────────────────────────────────
674    (not_congr (nat.sub_le_sub_right_iff _ _ _ hl)).2 $ not_le_of_gt hh);
id      └───────┘  └──────────────────────┘       └┘       └──────────┘ └┘
src  ─┘ └───────┘ └──────────────────────┘└─────┘  └───┘ └──────────┘  
typ  ─┘ └───────┘ └──────────────────────┘└─────┘└┘└───┘ └──────────┘└┘
doc  ─┘                                   └─────┘  └───┘               
txt  ─┘                                   └─────┘  └───┘               
par  ─┘                                   └─────┘  └───┘               
pid  ─┘                                   └─────┘  └───┘               
st   ────────────────────────────────────────────────────────────────────────
675    rwa [nat.add_sub_of_le hl] at this,
id          └───────────────┘ └┘
src    └───┘└───────────────┘  └───────┘
typ    └───┘└───────────────┘└┘└───────┘
doc    └───┘                   └───────┘
txt    └───┘                   └───────┘
par    └───┘                   └───────┘
pid       └┘                   └──────┘
st   ──────┘└──────────────────┘└──────┘
676  λal x h, al _ (nat.le_add_right _ _) (nat.add_lt_of_lt_sub_left h)⟩
id    └┘    └┘    └──────────────┘       └───────────────────────┘ 
src                 └──────────────┘       └───────────────────────┘
typ   └┘    └┘    └──────────────┘       └───────────────────────┘ 
677  
678  instance decidable_lo_hi_le (lo hi : ℕ) (P : ℕ → Prop) [H : decidable_pred P] : decidable (∀x, lo ≤ x → x ≤ hi → P x) :=
id                                                             └────────────┘     └───────┘     └┘       └┘    
src                                                            └────────────┘      └───────┘                
typ                                                            └────────────┘     └───────┘     └┘       └┘    
679  decidable_of_iff (∀x, lo ≤ x → x < hi + 1 → P x) $
id   └──────────────┘     └┘       └┘       
src  └──────────────┘                    
typ  └──────────────┘     └┘       └┘       
680  ball_congr $ λ x hl, imp_congr lt_succ_iff iff.rfl
id   └────────┘      └┘  └───────┘ └─────────┘ └─────┘
src  └────────┘           └───────┘ └─────────┘ └─────┘
typ  └────────┘      └┘  └───────┘ └─────────┘ └─────┘
681  
682  protected theorem bit0_le {n m : ℕ} (h : n ≤ m) : bit0 n ≤ bit0 m :=
id                                                 └──┘   └──┘ 
src                                                  └──┘    └──┘
typ                                                └──┘   └──┘ 
683  add_le_add h h
id   └────────┘  
src  └────────┘
typ  └────────┘  
684  
685  protected theorem bit1_le {n m : ℕ} (h : n ≤ m) : bit1 n ≤ bit1 m :=
id                                                 └──┘   └──┘ 
src                                                  └──┘    └──┘
typ                                                └──┘   └──┘ 
686  succ_le_succ (add_le_add h h)
id   └──────────┘  └────────┘  
src  └──────────┘  └────────┘
typ  └──────────┘  └────────┘  
687  
688  theorem bit_le : ∀ (b : bool) {n m : ℕ}, n ≤ m → bit b n ≤ bit b m
id                          └──┘                 └─┘    └─┘  
src                          └──┘                   └─┘      └─┘
typ                         └──┘                 └─┘    └─┘  
689  | tt n m h := nat.bit1_le h
id     └┘         └─────────┘
src    └┘          └─────────┘
typ    └┘         └─────────┘
690  | ff n m h := nat.bit0_le h
id     └┘         └─────────┘
src    └┘          └─────────┘
typ    └┘         └─────────┘
691  
692  theorem bit_ne_zero (b) {n} (h : n ≠ 0) : bit b n ≠ 0 :=
id                                           └─┘   
src                                           └─┘     
typ                                          └─┘   
693  by cases b; [exact nat.bit0_ne_zero h, exact nat.bit1_ne_zero _]
id                    └──────────────┘         └──────────────┘
src     └────┘   └────┘└──────────────┘   └────┘└──────────────┘└┘
typ     └────┘  └────┘└──────────────┘  └────┘└──────────────┘└┘
doc     └────┘    └────┘                   └────┘                └┘
txt     └────┘    └────┘                   └────┘                └┘
par     └────┘    └────┘                   └────┘                └┘
pid                                                           └┘
st     └────────────────────────────────────────────────────────────┘
694  
695  theorem bit0_le_bit : ∀ (b) {m n : ℕ}, m ≤ n → bit0 m ≤ bit b n
id                                            └──┘   └─┘  
src                                               └──┘    └─┘
typ                                           └──┘   └─┘  
696  | tt m n h := le_of_lt $ nat.bit0_lt_bit1 h
id     └┘         └──────┘   └──────────────┘
src    └┘          └──────┘   └──────────────┘
typ    └┘         └──────┘   └──────────────┘
697  | ff m n h := nat.bit0_le h
id     └┘         └─────────┘
src    └┘          └─────────┘
typ    └┘         └─────────┘
698  
699  theorem bit_le_bit1 : ∀ (b) {m n : ℕ}, m ≤ n → bit b m ≤ bit1 n
id                                            └─┘    └──┘ 
src                                               └─┘      └──┘
typ                                           └─┘    └──┘ 
700  | ff m n h := le_of_lt $ nat.bit0_lt_bit1 h
id     └┘         └──────┘   └──────────────┘
src    └┘          └──────┘   └──────────────┘
typ    └┘         └──────┘   └──────────────┘
701  | tt m n h := nat.bit1_le h
id     └┘         └─────────┘
src    └┘          └─────────┘
typ    └┘         └─────────┘
702  
703  theorem bit_lt_bit0 : ∀ (b) {n m : ℕ}, n < m → bit b n < bit0 m
id                                            └─┘    └──┘ 
src                                               └─┘      └──┘
typ                                           └─┘    └──┘ 
704  | tt n m h := nat.bit1_lt_bit0 h
id     └┘         └──────────────┘
src    └┘          └──────────────┘
typ    └┘         └──────────────┘
705  | ff n m h := nat.bit0_lt h
id     └┘         └─────────┘
src    └┘          └─────────┘
typ    └┘         └─────────┘
706  
707  theorem bit_lt_bit (a b) {n m : ℕ} (h : n < m) : bit a n < bit b m :=
id                                                └─┘    └─┘  
src                                                 └─┘      └─┘
typ                                               └─┘    └─┘  
708  lt_of_lt_of_le (bit_lt_bit0 _ h) (bit0_le_bit _ (le_refl _))
id   └────────────┘  └─────────┘      └─────────┘    └─────┘
src  └────────────┘  └─────────┘       └─────────┘    └─────┘
typ  └────────────┘  └─────────┘      └─────────┘    └─────┘
709  
710  /- partial subtraction -/
711  
712  /-- Partial predecessor operation. Returns `ppred n = some m`
713    if `n = m + 1`, otherwise `none`. -/
714  @[simp] def ppred : ℕ → option ℕ
id                         └────┘ 
src                         └────┘ 
typ                        └────┘ 
doc    └──┘
715  | 0     := none
id              └──┘
src             └──┘
typ             └──┘
716  | (n+1) := some n
id            └──┘
src            └──┘
typ           └──┘
717  
718  /-- Partial subtraction operation. Returns `psub m n = some k`
719    if `m = n + k`, otherwise `none`. -/
720  @[simp] def psub (m : ℕ) : ℕ → option ℕ
id                               └────┘ 
src                               └────┘ 
typ                              └────┘ 
doc    └──┘
721  | 0     := some m
id              └──┘ 
src             └──┘
typ             └──┘ 
722  | (n+1) := psub n >>= ppred
id            └──┘   └─┘ └───┘
src                   └─┘ └───┘
typ           └──┘   └─┘ └───┘
doc                        └───┘
723  
724  theorem pred_eq_ppred (n : ℕ) : pred n = (ppred n).get_or_else 0 :=
id                                  └──┘    └───┘  └─────────┘
src                                 └──┘     └───┘   └─────────┘
typ                                 └──┘    └───┘  └─────────┘
doc                                            └───┘
725  by cases n; refl
id            
src     └────┘   └────
typ     └────┘  └────
doc     └────┘   └────
txt     └────┘   └────
par     └────┘   └────
pid                 
st     └──────────────
726  
src  
typ  
doc  
txt  
par  
pid  
st   
727  theorem sub_eq_psub (m : ℕ) : ∀ n, m - n = (psub m n).get_or_else 0
id                                         └──┘   └─────────┘
src                                           └──┘     └─────────┘
typ                                        └──┘   └─────────┘
doc                                              └──┘
728  | 0     := rfl
id              └─┘
src             └─┘
typ             └─┘
729  | (n+1) := (pred_eq_ppred (m-n)).trans $
id             └───────────┘     └───┘
src             └───────────┘      └───┘
typ            └───────────┘     └───┘
730    by rw [sub_eq_psub, psub]; cases psub m n; refl
id            └─────────┘  └──┘         └──┘  
src       └──┘           └┘└──┘  └────┘└──┘    └────
typ       └──┘└─────────┘└┘└──┘  └────┘└──┘  └────
doc       └──┘           └┘└──┘  └────┘└──┘    └────
txt       └──┘           └┘      └────┘        └────
par       └──┘           └┘      └────┘        └────
pid         └┘           └┘                       
st       └──────────────┘└────┘└──────────────────────
731  
src  
typ  
doc  
txt  
par  
pid  
st   
732  @[simp] theorem ppred_eq_some {m : ℕ} : ∀ {n}, ppred n = some m ↔ succ m = n
id                                               └───┘   └──┘   └──┘   
src                                                └───┘    └──┘    └──┘   
typ                                              └───┘   └──┘   └──┘   
doc    └──┘                                         └───┘
733  | 0     := by split; intro h; contradiction
src                └───┘  └─────┘  └────────────┘
typ                └───┘  └─────┘  └────────────┘
doc                └───┘  └─────┘  └────────────┘
txt                └───┘  └─────┘  └────────────┘
par                └───┘  └─────┘  └────────────┘
pid                            └┘               
st                └─────────────────────────────┘
734  | (n+1) := by dsimp; split; intro h; injection h; subst n
id                                                         
src               └───┘  └───┘  └─────┘  └────────┘   └────┘ 
typ               └───┘  └───┘  └─────┘  └────────┘  └────┘
doc                └───┘  └───┘  └─────┘  └────────┘   └────┘ 
txt                └───┘  └───┘  └─────┘  └────────┘   └────┘ 
par                └───┘  └───┘  └─────┘  └────────┘   └────┘ 
pid                                   └┘                    
st                └────────────────────────────────────────────
735  
src  
typ  
doc  
txt  
par  
pid  
st   
736  @[simp] theorem ppred_eq_none : ∀ {n : ℕ}, ppred n = none ↔ n = 0
id                                            └───┘   └──┘   
src                                            └───┘    └──┘    
typ                                           └───┘   └──┘   
doc    └──┘                                     └───┘
737  | 0     := by simp
src                └───┘
typ                └───┘
doc                └───┘
txt                └───┘
par                └───┘
pid                    
st                └────┘
738  | (n+1) := by dsimp; split; contradiction
id       
src               └───┘  └───┘  └─────────────
typ               └───┘  └───┘  └─────────────
doc                └───┘  └───┘  └─────────────
txt                └───┘  └───┘  └─────────────
par                └───┘  └───┘  └─────────────
pid                                           
st                └────────────────────────────
739  
src  
typ  
doc  
txt  
par  
pid  
st   
740  theorem psub_eq_some {m : ℕ} : ∀ {n k}, psub m n = some k ↔ k + n = m
id                                       └──┘    └──┘       
src                                         └──┘      └──┘         
typ                                      └──┘    └──┘       
doc                                          └──┘
741  | 0     k := by simp [eq_comm]
id                         └─────┘
src                  └────┘└─────┘└┘
typ                  └────┘└─────┘└┘
doc                  └────┘       └┘
txt                  └────┘       └┘
par                  └────┘       └┘
pid                             
st                  └──────────────┘
742  | (n+1) k := by dsimp; apply option.bind_eq_some.trans; simp [psub_eq_some]
id       
src                 └───┘  └────┘                           └────┘            └─
typ                 └───┘  └────┘                           └────┘└──────────┘└─
doc                  └───┘  └────┘                           └────┘            └─
txt                  └───┘  └────┘                           └────┘            └─
par                  └───┘  └────┘                           └────┘            └─
pid                                                                         
st                  └────────────────────────────────────────────────────────────
743  
src  
typ  
doc  
txt  
par  
pid  
st   
744  theorem psub_eq_none (m n : ℕ) : psub m n = none ↔ m < n :=
id                                   └──┘    └──┘    
src                                  └──┘      └──┘    
typ                                  └──┘    └──┘    
doc                                   └──┘
745  begin
st   └─────
746    cases s : psub m n; simp [eq_comm],
id               └──┘          └─────┘
src    └────┘ └─┘└──┘    └────┘└─────┘
typ    └────┘ └─┘└──┘  └────┘└─────┘
doc    └────┘ └─┘└──┘    └────┘       
txt    └────┘ └─┘        └────┘       
par    └────┘ └─┘        └────┘       
pid          └─┘                   
st   ───────────────────────────────────┘└─
747    { show m < n, refine lt_of_not_ge (λ h, _),
id                       └──────────┘
src      └───┘    └─────┘└──────────┘  └────┘
typ      └───┘  └─────┘└──────────┘  └────┘
doc      └───┘     └─────┘              └────┘
txt      └───┘     └─────┘              └────┘
par      └───┘     └─────┘              └────┘
pid      └───┘                         └────┘
st   ───┘└──────────────────────────────────────┘└─
748      cases le.dest h with k e,
id             └─────┘ 
src      └────┘└─────┘ └───────┘
typ      └────┘└─────┘└───────┘
doc      └────┘        └───────┘
txt      └────┘        └───────┘
par      └────┘        └───────┘
pid                   └───────┘
st   ───────────────────────────┘└─
749      injection s.symm.trans (psub_eq_some.2 $ (add_comm _ _).trans e) },
id                 └──────────┘  └──────────┘      └──────┘            
src      └────────┘└──────────┘ └──────────┘└─┘  └──────┘└──────────┘ └┘
typ      └────────┘└──────────┘ └──────────┘└─┘  └──────┘└──────────┘└┘
doc      └────────┘                         └─┘          └──────────┘ └┘
txt      └────────┘                         └─┘          └──────────┘ └┘
par      └────────┘                         └─┘          └──────────┘ └┘
pid                                        └─┘          └──────────┘ 
st   ────────────────────────────────────────────────────────────────────┘└┘
750    { show n ≤ m, rw ← psub_eq_some.1 s, apply le_add_left }
id                     └──────────┘           └─────────┘
src      └───┘    └───┘└──────────┘└─┘   └────┘└─────────┘
typ      └───┘  └───┘└──────────┘└─┘  └────┘└─────────┘
doc      └───┘     └───┘            └─┘   └────┘           
txt      └───┘     └───┘            └─┘   └────┘           
par      └───┘     └───┘            └─┘   └────┘           
pid      └───┘       └─┘            └─┘                   
st   ─────────────┘└─────────────────────┘└──────────────────┘└─
751  end
st   ──┘
752  
753  theorem ppred_eq_pred {n} (h : 0 < n) : ppred n = some (pred n) :=
id                                         └───┘   └──┘  └──┘ 
src                                         └───┘    └──┘  └──┘
typ                                        └───┘   └──┘  └──┘ 
doc                                          └───┘
754  ppred_eq_some.2 $ succ_pred_eq_of_pos h
id   └───────────┘    └─────────────────┘ 
src  └───────────┘    └─────────────────┘
typ  └───────────┘    └─────────────────┘ 
755  
756  theorem psub_eq_sub {m n} (h : n ≤ m) : psub m n = some (m - n) :=
id                                        └──┘    └──┘    
src                                         └──┘      └──┘    
typ                                       └──┘    └──┘    
doc                                          └──┘
757  psub_eq_some.2 $ nat.sub_add_cancel h
id   └──────────┘    └────────────────┘ 
src  └──────────┘    └────────────────┘
typ  └──────────┘    └────────────────┘ 
758  
759  theorem psub_add (m n k) : psub m (n + k) = do x ← psub m n, psub x k :=
id                              └──┘              └──┘    └──┘  
src                             └──┘                  └──┘      └──┘
typ                             └──┘              └──┘    └──┘  
doc                             └──┘                    └──┘      └──┘
760  by induction k; simp [*, add_succ, bind_assoc]
id                           └──────┘  └────────┘
src     └────────┘   └───────┘└──────┘└┘└────────┘└─
typ     └────────┘  └───────┘└──────┘└┘└────────┘└─
doc     └────────┘   └───────┘        └┘          └─
txt     └────────┘   └───────┘        └┘          └─
par     └────────┘   └───────┘        └┘          └─
pid                     └──┘        └┘          
st     └────────────────────────────────────────────
761  
src  
typ  
doc  
txt  
par  
pid  
st   
762  /- pow -/
src  ──────────
typ  ──────────
doc  ──────────
txt  ──────────
par  ──────────
pid  ──────────
st   ──────────
763  
src  
typ  
doc  
txt  
par  
pid  
st   
764  attribute [simp] nat.pow_zero nat.pow_one
id                    └──────────┘ └─────────┘
src                   └──────────┘ └─────────┘
typ                   └──────────┘ └─────────┘
doc             └──┘
765  
766  @[simp] lemma one_pow : ∀ n : ℕ, 1 ^ n = 1
id                                      
src                                       
typ                                     
doc    └──┘
767  | 0 := rfl
id          └─┘
src         └─┘
typ         └─┘
768  | (k+1) := show 1^k * 1 = 1, by rw [mul_one, one_pow]
id                                  └─────┘  └─────┘
src                              └──┘└─────┘└┘       └─
typ                             └──┘└─────┘└┘└─────┘└─
doc                                  └──┘       └┘       └─
txt                                  └──┘       └┘       └─
par                                  └──┘       └┘       └─
pid                                    └┘       └┘       
st                                  └──────────┘└───────┘
769  
src  
typ  
doc  
txt  
par  
pid  
st   
770  theorem pow_add (a m n : ℕ) : a^(m + n) = a^m * a^n :=
id                                        
src                                             
typ                                       
771  by induction n; simp [*, pow_succ, mul_assoc]
id                           └──────┘  └───────┘
src     └────────┘   └───────┘└──────┘└┘└───────┘└─
typ     └────────┘  └───────┘└──────┘└┘└───────┘└─
doc     └────────┘   └───────┘        └┘         └─
txt     └────────┘   └───────┘        └┘         └─
par     └────────┘   └───────┘        └┘         └─
pid                     └──┘        └┘         
st     └───────────────────────────────────────────
772  
src  
typ  
doc  
txt  
par  
pid  
st   
773  theorem pow_two (a : ℕ) : a ^ 2 = a * a := show (1 * a) * a = _, by rw one_mul
id                                                              └─────┘
src                                                               └─┘└─────┘
typ                                                          └─┘└─────┘
doc                                                                      └─┘       
txt                                                                      └─┘       
par                                                                      └─┘       
pid                                                                               
st                                                                      └───────────
774  
src  
typ  
doc  
txt  
par  
pid  
st   
775  theorem pow_dvd_pow (a : ℕ) {m n : ℕ} (h : m ≤ n) : a^m ∣ a^n :=
id                                                    
src                                                        
typ                                                   
776  by rw [← nat.add_sub_cancel' h, pow_add]; apply dvd_mul_right
id            └─────────────────┘   └─────┘         └───────────┘
src     └────┘└─────────────────┘ └┘└─────┘  └────┘└───────────┘
typ     └────┘└─────────────────┘└┘└─────┘  └────┘└───────────┘
doc     └────┘                    └┘         └────┘             
txt     └────┘                    └┘         └────┘             
par     └────┘                    └┘         └────┘             
pid       └──┘                    └┘                           
st     └──────────────────────────┘└───────┘└─────────────────────
777  
src  
typ  
doc  
txt  
par  
pid  
st   
778  theorem pow_dvd_pow_of_dvd {a b : ℕ} (h : a ∣ b) : ∀ n:ℕ, a^n ∣ b^n
id                                                         
src                                                              
typ                                                        
779  | 0     := dvd_refl _
id              └──────┘
src             └──────┘
typ             └──────┘
780  | (n+1) := mul_dvd_mul (pow_dvd_pow_of_dvd n) h
id            └─────────┘  └────────────────┘    
src            └─────────┘
typ           └─────────┘  └────────────────┘    
781  
782  theorem mul_pow (a b n : ℕ) : (a * b) ^ n = a ^ n * b ^ n :=
id                                              
src                                                  
typ                                             
783  by induction n; simp [*, nat.pow_succ, mul_comm, mul_assoc, mul_left_comm]
id                           └──────────┘  └──────┘  └───────┘  └───────────┘
src     └────────┘   └───────┘└──────────┘└┘└──────┘└┘└───────┘└┘└───────────┘└─
typ     └────────┘  └───────┘└──────────┘└┘└──────┘└┘└───────┘└┘└───────────┘└─
doc     └────────┘   └───────┘            └┘        └┘         └┘             └─
txt     └────────┘   └───────┘            └┘        └┘         └┘             └─
par     └────────┘   └───────┘            └┘        └┘         └┘             └─
pid                     └──┘            └┘        └┘         └┘             
st     └────────────────────────────────────────────────────────────────────────
784  
src  
typ  
doc  
txt  
par  
pid  
st   
785  protected theorem pow_mul (a b n : ℕ) : n ^ (a * b) = (n ^ a) ^ b :=
id                                                        
src                                                           
typ                                                       
786  by induction b; simp [*, nat.succ_eq_add_one, nat.pow_add, mul_add, mul_comm]
id                           └─────────────────┘  └─────────┘  └─────┘  └──────┘
src     └────────┘   └───────┘└─────────────────┘└┘└─────────┘└┘└─────┘└┘└──────┘└─
typ     └────────┘  └───────┘└─────────────────┘└┘└─────────┘└┘└─────┘└┘└──────┘└─
doc     └────────┘   └───────┘                   └┘           └┘       └┘        └─
txt     └────────┘   └───────┘                   └┘           └┘       └┘        └─
par     └────────┘   └───────┘                   └┘           └┘       └┘        └─
pid                     └──┘                   └┘           └┘       └┘        
st     └───────────────────────────────────────────────────────────────────────────
787  
src  
typ  
doc  
txt  
par  
pid  
st   
788  theorem pow_pos {p : ℕ} (hp : 0 < p) : ∀ n : ℕ, 0 < p ^ n
id                                                   
src                                                    
typ                                                  
789  | 0 := by simp
src            └───┘
typ            └───┘
doc            └───┘
txt            └───┘
par            └───┘
pid                
st            └────┘
790  | (k+1) := mul_pos (pow_pos _) hp
id             └─────┘  └─────┘    └┘
src            └─────┘
typ            └─────┘  └─────┘    └┘
791  
792  lemma pow_eq_mul_pow_sub (p : ℕ) {m n : ℕ} (h : m ≤ n) : p ^ m * p ^ (n - m)  = p ^ n :=
id                                                                      
src                                                                            
typ                                                                     
793  by rw [←nat.pow_add, nat.add_sub_cancel' h]
id           └─────────┘  └─────────────────┘ 
src     └───┘└─────────┘└┘└─────────────────┘ └─
typ     └───┘└─────────┘└┘└─────────────────┘└─
doc     └───┘           └┘                    └─
txt     └───┘           └┘                    └─
par     └───┘           └┘                    └─
pid       └─┘           └┘                    
st     └───────────────┘└─────────────────────┘
794  
src  
typ  
doc  
txt  
par  
pid  
st   
795  lemma pow_lt_pow_succ {p : ℕ} (h : 1 < p) (n : ℕ) : p^n < p^(n+1) :=
id                                                      
src                                                          
typ                                                     
796  suffices p^n*1 < p^n*p, by simpa,
id               
src                        └───┘
typ                   └───┘
doc                             └───┘
txt                             └───┘
par                             └───┘
st                             └────┘
797  nat.mul_lt_mul_of_pos_left h (nat.pow_pos (lt_of_succ_lt h) n)
id   └────────────────────────┘   └─────────┘  └───────────┘   
src  └────────────────────────┘    └─────────┘  └───────────┘
typ  └────────────────────────┘   └─────────┘  └───────────┘   
798  
799  lemma lt_pow_self {p : ℕ} (h : 1 < p) : ∀ n : ℕ, n < p ^ n
id                                                   
src                                                     
typ                                                  
800  | 0 := by simp [zero_lt_one]
id                   └─────────┘
src            └────┘└─────────┘└┘
typ            └────┘└─────────┘└┘
doc            └────┘           └┘
txt            └────┘           └┘
par            └────┘           └┘
pid                           
st            └──────────────────┘
801  | (n+1) := calc
id      
src      
typ     
802    n + 1 < p^n + 1 : nat.add_lt_add_right (lt_pow_self _) _
id                   └──────────────────┘  └─────────┘
src                   └──────────────────┘
typ                  └──────────────────┘  └─────────┘
803      ... ≤ p ^ (n+1) : pow_lt_pow_succ h _
id                      └─────────────┘ 
src                      └─────────────┘
typ                     └─────────────┘ 
804  
805  lemma pow_right_strict_mono {x : ℕ} (k : 2 ≤ x) : strict_mono (nat.pow x) :=
id                                                  └─────────┘  └─────┘ 
src                                                  └─────────┘  └─────┘
typ                                                 └─────────┘  └─────┘ 
doc                                                    └─────────┘
806  λ _ _, pow_lt_pow_of_lt_right k
id        └────────────────────┘ 
src         └────────────────────┘
typ       └────────────────────┘ 
807  
808  lemma pow_le_iff_le_right {x m n : ℕ} (k : 2 ≤ x) : x^m ≤ x^n ↔ m ≤ n :=
id                                                          
src                                                              
typ                                                         
809  strict_mono.le_iff_le (pow_right_strict_mono k)
id   └───────────────────┘  └───────────────────┘ 
src  └───────────────────┘  └───────────────────┘
typ  └───────────────────┘  └───────────────────┘ 
810  
811  lemma pow_lt_iff_lt_right {x m n : ℕ} (k : 2 ≤ x) : x^m < x^n ↔ m < n :=
id                                                          
src                                                              
typ                                                         
812  strict_mono.lt_iff_lt (pow_right_strict_mono k)
id   └───────────────────┘  └───────────────────┘ 
src  └───────────────────┘  └───────────────────┘
typ  └───────────────────┘  └───────────────────┘ 
813  
814  lemma pow_right_injective {x : ℕ} (k : 2 ≤ x) : function.injective (nat.pow x) :=
id                                                └────────────────┘  └─────┘ 
src                                                └────────────────┘  └─────┘
typ                                               └────────────────┘  └─────┘ 
815  strict_mono.injective (pow_right_strict_mono k)
id   └───────────────────┘  └───────────────────┘ 
src  └───────────────────┘  └───────────────────┘
typ  └───────────────────┘  └───────────────────┘ 
816  
817  lemma pow_left_strict_mono {m : ℕ} (k : 1 ≤ m) : strict_mono (λ (x : ℕ), x^m) :=
id                                                 └─────────┘            
src                                                 └─────────┘             
typ                                                └─────────┘            
doc                                                   └─────────┘
818  λ _ _ h, pow_lt_pow_of_lt_left h k
id         └───────────────────┘  
src           └───────────────────┘
typ        └───────────────────┘  
819  
820  lemma pow_le_iff_le_left {m x y : ℕ} (k : 1 ≤ m) : x^m ≤ y^m ↔ x ≤ y :=
id                                                         
src                                                             
typ                                                        
821  strict_mono.le_iff_le (pow_left_strict_mono k)
id   └───────────────────┘  └──────────────────┘ 
src  └───────────────────┘  └──────────────────┘
typ  └───────────────────┘  └──────────────────┘ 
822  
823  lemma pow_lt_iff_lt_left {m x y : ℕ} (k : 1 ≤ m) : x^m < y^m ↔ x < y :=
id                                                         
src                                                             
typ                                                        
824  strict_mono.lt_iff_lt (pow_left_strict_mono k)
id   └───────────────────┘  └──────────────────┘ 
src  └───────────────────┘  └──────────────────┘
typ  └───────────────────┘  └──────────────────┘ 
825  
826  lemma pow_left_injective {m : ℕ} (k : 1 ≤ m) : function.injective (λ (x : ℕ), x^m) :=
id                                               └────────────────┘            
src                                               └────────────────┘             
typ                                              └────────────────┘            
827  strict_mono.injective (pow_left_strict_mono k)
id   └───────────────────┘  └──────────────────┘ 
src  └───────────────────┘  └──────────────────┘
typ  └───────────────────┘  └──────────────────┘ 
828  
829  lemma not_pos_pow_dvd : ∀ {p k : ℕ} (hp : 1 < p) (hk : 1 < k), ¬ p^k ∣ p
id                                                               
src                                                                  
typ                                                              
830  | (succ p) (succ k) hp hk h :=
id              └──┘   └┘
src              └──┘
typ             └──┘   └┘
831    have (succ p)^k * succ p ∣ 1 * succ p, by simpa,
id           └──┘      └──┘       └──┘
src          └──┘      └──┘       └──┘       └───┘
typ          └──┘      └──┘       └──┘       └───┘
doc                                              └───┘
txt                                              └───┘
par                                              └───┘
st                                              └────┘
832    have (succ p) ^ k ∣ 1, from dvd_of_mul_dvd_mul_right (succ_pos _) this,
id           └──┘                └──────────────────────┘  └──────┘    └──┘
src          └──┘                └──────────────────────┘  └──────┘
typ          └──┘                └──────────────────────┘  └──────┘    └──┘
833    have he : (succ p) ^ k = 1, from eq_one_of_dvd_one this,
id                └──┘                └───────────────┘ └──┘
src               └──┘                └───────────────┘
typ               └──┘                └───────────────┘ └──┘
834    have k < (succ p) ^ k, from lt_pow_self hp k,
id              └──┘             └─────────┘
src             └──┘             └─────────┘
typ             └──┘             └─────────┘
835    have k < 1, by rwa [he] at this,
id                        └┘
src                  └───┘  └───────┘
typ                  └───┘└┘└───────┘
doc                   └───┘  └───────┘
txt                   └───┘  └───────┘
par                   └───┘  └───────┘
pid                      └┘  └──────┘
st                   └──────┘└──────┘
836    have k = 0, from eq_zero_of_le_zero $ le_of_lt_succ this,
id                     └────────────────┘   └───────────┘ └──┘
src                    └────────────────┘   └───────────┘
typ                    └────────────────┘   └───────────┘ └──┘
837    have 1 < 1, by rwa [this] at hk,
id                        └──┘
src                  └───┘    └─────┘
typ                  └───┘└──┘└─────┘
doc                   └───┘    └─────┘
txt                   └───┘    └─────┘
par                   └───┘    └─────┘
pid                      └┘    └────┘
st                   └────────┘└────┘
838    absurd this dec_trivial
id     └────┘ └──┘ └─────────┘
src    └────┘      └─────────┘
typ    └────┘ └──┘ └─────────┘
doc                └─────────┘
839  
840  @[simp] theorem bodd_div2_eq (n : ℕ) : bodd_div2 n = (bodd n, div2 n) :=
id                                         └───────┘   └──┘   └──┘ 
src                                        └───────┘    └──┘    └──┘
typ                                        └───────┘   └──┘   └──┘ 
doc    └──┘
841  by unfold bodd div2; cases bodd_div2 n; refl
id                              └───────┘ 
src     └──────────────┘  └────┘└───────┘   └────
typ     └──────────────┘  └────┘└───────┘  └────
doc     └──────────────┘  └────┘            └────
txt     └──────────────┘  └────┘            └────
par     └──────────────┘  └────┘            └────
pid           └────────┘                       
st     └──────────────────────────────────────────
842  
src  
typ  
doc  
txt  
par  
pid  
st   
843  @[simp] lemma bodd_bit0 (n) : bodd (bit0 n) = ff := bodd_bit ff n
id                                 └──┘  └──┘    └┘    └──────┘ └┘ 
src                                └──┘  └──┘     └┘    └──────┘ └┘
typ                                └──┘  └──┘    └┘    └──────┘ └┘ 
doc    └──┘
844  @[simp] lemma bodd_bit1 (n) : bodd (bit1 n) = tt := bodd_bit tt n
id                                 └──┘  └──┘    └┘    └──────┘ └┘ 
src                                └──┘  └──┘     └┘    └──────┘ └┘
typ                                └──┘  └──┘    └┘    └──────┘ └┘ 
doc    └──┘
845  
846  @[simp] lemma div2_bit0 (n) : div2 (bit0 n) = n := div2_bit ff n
id                                 └──┘  └──┘        └──────┘ └┘ 
src                                └──┘  └──┘          └──────┘ └┘
typ                                └──┘  └──┘        └──────┘ └┘ 
doc    └──┘
847  @[simp] lemma div2_bit1 (n) : div2 (bit1 n) = n := div2_bit tt n
id                                 └──┘  └──┘        └──────┘ └┘ 
src                                └──┘  └──┘          └──────┘ └┘
typ                                └──┘  └──┘        └──────┘ └┘ 
doc    └──┘
848  
849  /- iterate -/
850  
851  section
852  variables {α : Sort*} (op : α → α)
853  
854  @[simp] theorem iterate_zero (a : α) : op^[0] a = a := rfl
id                                         └┘└┘        └─┘
src                                           └┘          └─┘
typ                                        └┘└┘        └─┘
doc    └──┘
855  
856  @[simp] theorem iterate_succ (n : ℕ) (a : α) : op^[succ n] a = (op^[n]) (op a) := rfl
id                                                └┘└┘└──┘     └┘└┘   └┘      └─┘
src                                                  └┘└──┘         └┘             └─┘
typ                                               └┘└┘└──┘     └┘└┘   └┘      └─┘
doc    └──┘
857  
858  theorem iterate_add : ∀ (m n : ℕ) (a : α), op^[m + n] a = (op^[m]) (op^[n] a)
id                                           └┘└┘      └┘└┘   └┘└┘ 
src                                              └┘           └┘      └┘ 
typ                                          └┘└┘      └┘└┘   └┘└┘ 
859  | m 0 a := rfl
id              └─┘
src             └─┘
typ             └─┘
860  | m (succ n) a := iterate_add m n _
id       └──┘        └─────────┘
src       └──┘
typ      └──┘        └─────────┘
861  
862  theorem iterate_succ' (n : ℕ) (a : α) : op^[succ n] a = op (op^[n] a) :=
id                                         └┘└┘└──┘    └┘  └┘└┘ 
src                                           └┘└──┘            └┘ 
typ                                        └┘└┘└──┘    └┘  └┘└┘ 
863  by rw [← one_add, iterate_add]; refl
id            └─────┘  └─────────┘
src     └────┘└─────┘└┘└─────────┘  └────
typ     └────┘└─────┘└┘└─────────┘  └────
doc     └────┘       └┘             └────
txt     └────┘       └┘             └────
par     └────┘       └┘             └────
pid       └──┘       └┘                 
st     └────────────┘└───────────┘└──────
864  
src  
typ  
doc  
txt  
par  
pid  
st   
865  theorem iterate₀ {α : Type u} {op : α → α} {x : α} (H : op x = x) {n : ℕ} :
id                                                        └┘          
src                                                                        
typ                                                       └┘          
866    op^[n] x = x :=
id     └┘└┘   
src      └┘    
typ    └┘└┘   
867  by induction n; [simp only [iterate_zero], simp only [iterate_succ', H, *]]
id                             └──────────┘              └───────────┘  
src     └────────┘   └─────────┘└──────────┘  └─────────┘└───────────┘└┘ └──┘
typ     └────────┘  └─────────┘└──────────┘  └─────────┘└───────────┘└┘└──┘
doc     └────────┘    └─────────┘              └─────────┘             └┘ └──┘
txt     └────────┘    └─────────┘              └─────────┘             └┘ └──┘
par     └────────┘    └─────────┘              └─────────┘             └┘ └──┘
pid                      └──┘└┘                  └──┘└┘             └┘ └──┘
st     └───────────────────────────────────────────────────────────────────────┘
868  
869  theorem iterate₁ {α : Type u} {β : Type v} {op : α → α} {op' : β → β} {op'' : α → β}
id                                                                                
typ                                                                               
870    (H : ∀ x, op' (op'' x) = op'' (op x)) {n : ℕ} {x : α} :
id              └─┘  └──┘    └──┘  └┘                
src                                              
typ             └─┘  └──┘    └──┘  └┘                
871    op'^[n] (op'' x) = op'' (op^[n] x) :=
id     └─┘└┘  └──┘    └──┘  └┘└┘ 
src       └┘                    └┘ 
typ    └─┘└┘  └──┘    └──┘  └┘└┘ 
872  by induction n; [simp only [iterate_zero], simp only [iterate_succ', H, *]]
id                             └──────────┘              └───────────┘  
src     └────────┘   └─────────┘└──────────┘  └─────────┘└───────────┘└┘ └──┘
typ     └────────┘  └─────────┘└──────────┘  └─────────┘└───────────┘└┘└──┘
doc     └────────┘    └─────────┘              └─────────┘             └┘ └──┘
txt     └────────┘    └─────────┘              └─────────┘             └┘ └──┘
par     └────────┘    └─────────┘              └─────────┘             └┘ └──┘
pid                      └──┘└┘                  └──┘└┘             └┘ └──┘
st     └───────────────────────────────────────────────────────────────────────┘
873  
874  theorem iterate₂ {α : Type u} {op : α → α} {op' : α → α → α} (H : ∀ x y, op (op' x y) = op' (op x) (op y)) {n : ℕ} {x y : α} :
id                                                                     └┘  └─┘     └─┘  └┘    └┘                  
src                                                                                                                 
typ                                                                    └┘  └─┘     └─┘  └┘    └┘                  
875    op^[n] (op' x y) = op' (op^[n] x) (op^[n] y) :=
id     └┘└┘  └─┘     └─┘  └┘└┘    └┘└┘ 
src      └┘                    └┘        └┘ 
typ    └┘└┘  └─┘     └─┘  └┘└┘    └┘└┘ 
876  by induction n; [simp only [iterate_zero], simp only [iterate_succ', H, *]]
id                             └──────────┘              └───────────┘  
src     └────────┘   └─────────┘└──────────┘  └─────────┘└───────────┘└┘ └──┘
typ     └────────┘  └─────────┘└──────────┘  └─────────┘└───────────┘└┘└──┘
doc     └────────┘    └─────────┘              └─────────┘             └┘ └──┘
txt     └────────┘    └─────────┘              └─────────┘             └┘ └──┘
par     └────────┘    └─────────┘              └─────────┘             └┘ └──┘
pid                      └──┘└┘                  └──┘└┘             └┘ └──┘
st     └───────────────────────────────────────────────────────────────────────┘
877  
878  theorem iterate_cancel {α : Type u} {op op' : α → α} (H : ∀ x, op (op' x) = x) {n : ℕ} {x : α} : op^[n] (op'^[n] x) = x :=
id                                                               └┘  └─┘                      └┘└┘  └─┘└┘    
src                                                                                                   └┘      └┘     
typ                                                              └┘  └─┘                      └┘└┘  └─┘└┘    
879  by induction n; [refl, rwa [iterate_succ, iterate_succ', H]]
id                             └──────────┘  └───────────┘  
src     └────────┘   └──┘  └───┘└──────────┘└┘└───────────┘└┘ 
typ     └────────┘  └──┘  └───┘└──────────┘└┘└───────────┘└┘
doc     └────────┘    └──┘  └───┘            └┘             └┘ 
txt     └────────┘    └──┘  └───┘            └┘             └┘ 
par     └────────┘    └──┘  └───┘            └┘             └┘ 
pid                           └┘            └┘             └┘ 
st     └────────────────────────┘└──────────┘└─────────────┘└─┘
880  
881  theorem iterate_inj {α : Type u} {op : α → α} (Hinj : function.injective op) (n : ℕ) (x y : α)
id                                                       └────────────────┘ └┘                
src                                                        └────────────────┘          
typ                                                      └────────────────┘ └┘                
882    (H : (op^[n] x) = (op^[n] y)) : x = y :=
id           └┘└┘     └┘└┘        
src            └┘         └┘          
typ          └┘└┘     └┘└┘        
883  by induction n with n ih; simp only [iterate_zero, iterate_succ'] at H;
id                                       └──────────┘  └───────────┘
src     └────────┘ └────────┘  └─────────┘└──────────┘└┘└───────────┘└────┘
typ     └────────┘└────────┘  └─────────┘└──────────┘└┘└───────────┘└────┘
doc     └────────┘ └────────┘  └─────────┘            └┘             └────┘
txt     └────────┘ └────────┘  └─────────┘            └┘             └────┘
par     └────────┘ └────────┘  └─────────┘            └┘             └────┘
pid               └───────┘      └──┘└┘            └┘             └──┘
st     └─────────────────────────────────────────────────────────────────────
884  [exact H, exact ih (Hinj H)]
id                 └┘  └──┘ 
src  └────┘   └────┘        
typ  └────┘  └────┘└┘ └──┘
doc   └────┘   └────┘        
txt   └────┘   └────┘        
par   └────┘   └────┘        
pid                        
st   ───────────────────────────┘
885  
886  end
887  
888  /- size and shift -/
889  
890  theorem shiftl'_ne_zero_left (b) {m} (h : m ≠ 0) (n) : shiftl' b m n ≠ 0 :=
id                                                        └─────┘    
src                                                        └─────┘       
typ                                                       └─────┘    
891  by induction n; simp [shiftl', bit_ne_zero, *]
id                        └─────┘  └─────────┘
src     └────────┘   └────┘└─────┘└┘└─────────┘└────
typ     └────────┘  └────┘└─────┘└┘└─────────┘└────
doc     └────────┘   └────┘       └┘           └────
txt     └────────┘   └────┘       └┘           └────
par     └────────┘   └────┘       └┘           └────
pid                            └┘           └──┘
st     └────────────────────────────────────────────
892  
src  
typ  
doc  
txt  
par  
pid  
st   
893  theorem shiftl'_tt_ne_zero (m) : ∀ {n} (h : n ≠ 0), shiftl' tt m n ≠ 0
id                                                   └─────┘ └┘   
src                                                     └─────┘ └┘     
typ                                                  └─────┘ └┘   
894  | 0        h := absurd rfl h
id                  └────┘ └─┘
src                  └────┘ └─┘
typ                 └────┘ └─┘
895  | (succ n) _ := nat.bit1_ne_zero _
id      └──┘         └──────────────┘
src     └──┘         └──────────────┘
typ     └──┘         └──────────────┘
896  
897  @[simp] theorem size_zero : size 0 = 0 := rfl
id                               └──┘         └─┘
src                              └──┘         └─┘
typ                              └──┘         └─┘
doc    └──┘
898  
899  @[simp] theorem size_bit {b n} (h : bit b n ≠ 0) : size (bit b n) = succ (size n) :=
id                                       └─┘         └──┘  └─┘     └──┘  └──┘ 
src                                      └─┘           └──┘  └─┘       └──┘  └──┘
typ                                      └─┘         └──┘  └─┘     └──┘  └──┘ 
doc    └──┘
900  begin
st   └─────
901    rw size,
id        └──┘
src    └─┘└──┘
typ    └─┘└──┘
doc    └─┘
txt    └─┘
par    └─┘
pid      
st   ────────┘└─
902    conv { to_lhs, rw [binary_rec], simp [h] },
id                        └────────┘         
src    └─────┘└────┘└┘└──┘└────────┘└┘└────┘ └┘
typ    └─────┘└────┘└┘└──┘└────────┘└┘└────┘└┘
txt    └─────┘└────┘└┘└──┘          └┘└────┘ └┘
par    └─────┘└────┘└┘└──┘          └┘└────┘ └┘
pid        └────────────┘          └───────┘ └─┘
st   ───────┘└─────┘└──────────────┘ └─────────┘└┘
903    rw div2_bit, refl
id        └──────┘
src    └─┘└──────┘  └───┘
typ    └─┘└──────┘  └───┘
doc    └─┘          └───┘
txt    └─┘          └───┘
par    └─┘          └───┘
pid                    
st   ────────────┘└─────┘
904  end
st   └─┘
905  
906  @[simp] theorem size_bit0 {n} (h : n ≠ 0) : size (bit0 n) = succ (size n) :=
id                                             └──┘  └──┘    └──┘  └──┘ 
src                                             └──┘  └──┘     └──┘  └──┘
typ                                            └──┘  └──┘    └──┘  └──┘ 
doc    └──┘
907  @size_bit ff n (nat.bit0_ne_zero h)
id    └──────┘ └┘   └──────────────┘ 
src   └──────┘ └┘    └──────────────┘
typ   └──────┘ └┘   └──────────────┘ 
908  
909  @[simp] theorem size_bit1 (n) : size (bit1 n) = succ (size n) :=
id                                   └──┘  └──┘    └──┘  └──┘ 
src                                  └──┘  └──┘     └──┘  └──┘
typ                                  └──┘  └──┘    └──┘  └──┘ 
doc    └──┘
910  @size_bit tt n (nat.bit1_ne_zero n)
id    └──────┘ └┘   └──────────────┘ 
src   └──────┘ └┘    └──────────────┘
typ   └──────┘ └┘   └──────────────┘ 
911  
912  @[simp] theorem size_one : size 1 = 1 := by apply size_bit1 0
id                              └──┘                  └───────┘
src                             └──┘            └────┘└───────┘└──
typ                             └──┘            └────┘└───────┘└──
doc    └──┘                                      └────┘         └──
txt                                              └────┘         └──
par                                              └────┘         └──
pid                                                            └─
st                                              └──────────────────
913  
src  
typ  
doc  
txt  
par  
pid  
st   
914  @[simp] theorem size_shiftl' {b m n} (h : shiftl' b m n ≠ 0) :
id                                             └─────┘    
src                                            └─────┘       
typ                                            └─────┘    
doc    └──┘
915    size (shiftl' b m n) = size m + n :=
id     └──┘  └─────┘      └──┘   
src    └──┘  └─────┘         └──┘   
typ    └──┘  └─────┘      └──┘   
916  begin
st   └─────
917    induction n with n IH; simp [shiftl'] at h ⊢,
id                                 └─────┘
src    └────────┘ └────────┘  └────┘└─────┘└──────┘
typ    └────────┘└────────┘  └────┘└─────┘└──────┘
doc    └────────┘ └────────┘  └────┘       └──────┘
txt    └────────┘ └────────┘  └────┘       └──────┘
par    └────────┘ └────────┘  └────┘       └──────┘
pid              └───────┘             └────┘
st   ─────────────────────────────────────────────┘└─
918    rw [size_bit h, nat.add_succ],
id         └──────┘   └──────────┘
src    └──┘└──────┘ └┘└──────────┘
typ    └──┘└──────┘└┘└──────────┘
doc    └──┘         └┘            
txt    └──┘         └┘            
par    └──┘         └┘            
pid      └┘         └┘            
st   ───────────────┘└────────────┘└─
919    by_cases s0 : shiftl' b m n = 0; [skip, rw [IH s0]],
id                   └─────┘                  └┘ └┘
src    └───────┘  └─┘└─────┘   └┘  └──┘  └──┘    
typ    └───────┘  └─┘└─────┘└┘  └──┘  └──┘└┘└┘
doc    └───────┘  └─┘           └┘   └──┘  └──┘    
txt    └───────┘  └─┘           └┘   └──┘  └──┘    
par    └───────┘  └─┘           └┘   └──┘  └──┘    
pid              └─┘                      └┘    
st   ─────────────────────────────────────────────┘└───┘└─
920    rw s0 at h ⊢,
id        └┘
src    └─┘  └─────┘
typ    └─┘└┘└─────┘
doc    └─┘  └─────┘
txt    └─┘  └─────┘
par    └─┘  └─────┘
pid        └─────┘
st   ─────────────┘└─
921    cases b, {exact absurd rfl h},
id                    └────┘ └─┘ 
src    └────┘    └────┘└────┘└─┘
typ    └────┘   └────┘└────┘└─┘
doc    └────┘    └────┘         
txt    └────┘    └────┘         
par    └────┘    └────┘         
pid                           
st   ────────┘└───────────────────┘└┘
922    have : shiftl' tt m n + 1 = 1 := congr_arg (+1) s0,
id            └─────┘ └┘             └───────┘     └┘
src    └─────┘└─────┘└┘  └─┘ └────┘└───────┘ └──┘
typ    └─────┘└─────┘└┘└─┘ └────┘└───────┘└──┘└┘
doc    └─────┘            └─┘ └────┘          └──┘
txt    └─────┘            └─┘ └────┘          └──┘
par    └─────┘            └─┘ └────┘          └──┘
pid    └───┘└┘            └─┘ └───┘          └──┘
st   ───────────────────────────────────────────────────┘└─
923    rw [shiftl'_tt_eq_mul_pow] at this,
id         └───────────────────┘
src    └──┘└───────────────────┘└───────┘
typ    └──┘└───────────────────┘└───────┘
doc    └──┘                     └───────┘
txt    └──┘                     └───────┘
par    └──┘                     └───────┘
pid      └┘                     └──────┘
st   ──────────────────────────┘└──────┘└─
924    have m0 := succ_inj (eq_one_of_dvd_one ⟨_, this.symm⟩),
id                └──────┘  └───────────────┘     └───────┘
src    └─────────┘└──────┘ └───────────────┘ └─┘└───────┘└┘
typ    └─────────┘└──────┘ └───────────────┘ └─┘└───────┘└┘
doc    └─────────┘                           └─┘         └┘
txt    └─────────┘                           └─┘         └┘
par    └─────────┘                           └─┘         └┘
pid    └─────┘└─┘                           └─┘         └┘
st   ───────────────────────────────────────────────────────┘└─
925    subst m0,
id           └┘
src    └────┘
typ    └────┘└┘
doc    └────┘
txt    └────┘
par    └────┘
pid         
st   ─────────┘└─
926    simp at this,
src    └──────────┘
typ    └──────────┘
doc    └──────────┘
txt    └──────────┘
par    └──────────┘
pid        └─────┘
st   ─────────────┘└─
927    have : n = 0 := eq_zero_of_le_zero (le_of_not_gt $ λ hn,
id                    └────────────────┘  └──────────┘
src    └─────┘  └────┘└────────────────┘ └──────────┘  └────
typ    └─────┘ └────┘└────────────────┘ └──────────┘  └────
doc    └─────┘  └────┘                                 └────
txt    └─────┘  └────┘                                 └────
par    └─────┘  └────┘                                 └────
pid    └───┘└┘  └───┘                                 └────
st   ───────────────────────────────────────────────────────────
928      ne_of_gt (pow_lt_pow_of_lt_right dec_trivial hn) this),
id       └──────┘  └────────────────────┘ └─────────┘     └──┘
src  ───┘└──────┘ └────────────────────┘└─────────┘  └┘    
typ  ───┘└──────┘ └────────────────────┘└─────────┘  └┘└──┘
doc  ───┘                               └─────────┘  └┘    
txt  ───┘                                            └┘    
par  ───┘                                            └┘    
pid  ───┘                                            └┘    
st   ─────────────────────────────────────────────────────────┘└─
929    subst n, refl
id           
src    └────┘   └───┘
typ    └────┘  └───┘
doc    └────┘   └───┘
txt    └────┘   └───┘
par    └────┘   └───┘
pid                
st   ────────┘└─────┘
930  end
st   └─┘
931  
932  @[simp] theorem size_shiftl {m} (h : m ≠ 0) (n) :
id                                         
src                                         
typ                                        
doc    └──┘
933    size (shiftl m n) = size m + n :=
id     └──┘  └────┘     └──┘   
src    └──┘  └────┘       └──┘   
typ    └──┘  └────┘     └──┘   
934  size_shiftl' (shiftl'_ne_zero_left _ h _)
id   └──────────┘  └──────────────────┘   
src  └──────────┘  └──────────────────┘
typ  └──────────┘  └──────────────────┘   
935  
936  theorem lt_size_self (n : ℕ) : n < 2^size n :=
id                                    └──┘ 
src                                    └──┘
typ                                   └──┘ 
937  begin
st   └─────
938    rw [← one_shiftl],
id           └────────┘
src    └────┘└────────┘
typ    └────┘└────────┘
doc    └────┘          
txt    └────┘          
par    └────┘          
pid      └──┘          
st   ─────────────────┘└──
939    have : ∀ {n}, n = 0 → n < shiftl 1 (size n) :=
id                             └────┘    └──┘
src    └─────┘ └──┘  └─┘  └────┘└─┘ └──┘ └────
typ    └─────┘ └──┘  └─┘  └────┘└─┘ └──┘ └────
doc    └─────┘ └──┘   └─┘         └─┘      └────
txt    └─────┘ └──┘   └─┘         └─┘      └────
par    └─────┘ └──┘   └─┘         └─┘      └────
pid    └───┘└┘ └──┘   └─┘         └─┘      └───
st   ─────────────────────────────────────────────────
940      λ n e, by subst e; exact dec_trivial,
id                               └─────────┘
src  ───┘ └────┘  └────┘ └┘└────┘└─────────┘
typ  ───┘ └────┘  └────┘└┘└────┘└─────────┘
doc  ───┘ └────┘  └────┘ └┘└────┘└─────────┘
txt  ───┘ └────┘  └────┘ └┘└────┘
par  ───┘ └────┘  └────┘ └┘└────┘
pid  ───┘ └────┘  └─────┘ └──────┘
st   ────────────┘└─────────────────────────┘└─
941    apply binary_rec _ _ n, {apply this rfl},
id           └────────┘              └──┘ └─┘
src    └────┘└────────┘└───┘    └────┘    └─┘
typ    └────┘└────────┘└───┘   └────┘└──┘└─┘
doc    └────┘          └───┘    └────┘    
txt    └────┘          └───┘    └────┘    
par    └────┘          └───┘    └────┘    
pid                   └───┘             
st   ───────────────────────┘└───────────────┘└┘
942    intros b n IH,
src    └───────────┘
typ    └───────────┘
doc    └───────────┘
txt    └───────────┘
par    └───────────┘
pid          └─────┘
st   ──────────────┘└─
943    by_cases bit b n = 0, {apply this h},
id              └─┘               └──┘ 
src    └───────┘└─┘   └┘   └────┘    
typ    └───────┘└─┘ └┘   └────┘└──┘
doc    └───────┘      └┘   └────┘    
txt    └───────┘      └┘   └────┘    
par    └───────┘      └┘   └────┘    
pid                              
st   ─────────────────────┘└─────────────┘└┘
944    rw [size_bit h, shiftl_succ],
id         └──────┘   └─────────┘
src    └──┘└──────┘ └┘└─────────┘
typ    └──┘└──────┘└┘└─────────┘
doc    └──┘         └┘           
txt    └──┘         └┘           
par    └──┘         └┘           
pid      └┘         └┘           
st   ───────────────┘└───────────┘└──
945    exact bit_lt_bit0 _ IH
id           └─────────┘   └┘
src    └────┘└─────────┘└─┘  
typ    └────┘└─────────┘└─┘└┘
doc    └────┘           └─┘  
txt    └────┘           └─┘  
par    └────┘           └─┘  
pid                    └─┘  
st   ────────────────────────┘
946  end
st   └─┘
947  
948  theorem size_le {m n : ℕ} : size m ≤ n ↔ m < 2^n :=
id                              └──┘        
src                             └──┘           
typ                             └──┘        
949  ⟨λ h, lt_of_lt_of_le (lt_size_self _) (pow_le_pow_of_le_right dec_trivial h),
id        └────────────┘  └──────────┘     └────────────────────┘ └─────────┘ 
src        └────────────┘  └──────────┘     └────────────────────┘ └─────────┘
typ       └────────────┘  └──────────┘     └────────────────────┘ └─────────┘ 
doc                                                                └─────────┘
950  begin
st   └─────
951    rw [← one_shiftl], revert n,
id           └────────┘
src    └────┘└────────┘  └──────┘
typ    └────┘└────────┘  └──────┘
doc    └────┘            └──────┘
txt    └────┘            └──────┘
par    └────┘            └──────┘
pid      └──┘                  └┘
st   ─────────────────┘└─────────┘└─
952    apply binary_rec _ _ m,
id           └────────┘     
src    └────┘└────────┘└───┘
typ    └────┘└────────┘└───┘
doc    └────┘          └───┘
txt    └────┘          └───┘
par    └────┘          └───┘
pid                   └───┘
st   ───────────────────────┘└─
953    { intros n h, apply zero_le },
id                         └─────┘
src      └────────┘  └────┘└─────┘
typ      └────────┘  └────┘└─────┘
doc      └────────┘  └────┘       
txt      └────────┘  └────┘       
par      └────────┘  └────┘       
pid            └──┘              
st   ───┘└────────┘└──────────────┘└┘
954    { intros b m IH n h,
src      └───────────────┘
typ      └───────────────┘
doc      └───────────────┘
txt      └───────────────┘
par      └───────────────┘
pid            └─────────┘
st   ────────────────────┘└─
955      by_cases e : bit b m = 0, { rw e, apply zero_le },
id                    └─┘                    └─────┘
src      └───────┘ └─┘└─┘  └┘    └─┘   └────┘└─────┘
typ      └───────┘ └─┘└─┘└┘    └─┘  └────┘└─────┘
doc      └───────┘ └─┘      └┘    └─┘   └────┘       
txt      └───────┘ └─┘      └┘    └─┘   └────┘       
par      └───────┘ └─┘      └┘    └─┘   └────┘       
pid               └─┘                           
st   ───────────────────────────┘└──┘└──┘└──────────────┘└┘
956      rw [size_bit e],
id           └──────┘ 
src      └──┘└──────┘ 
typ      └──┘└──────┘
doc      └──┘         
txt      └──┘         
par      └──┘         
pid        └┘         
st   ─────────────────┘└──
957      cases n with n,
id             
src      └────┘ └─────┘
typ      └────┘└─────┘
doc      └────┘ └─────┘
txt      └────┘ └─────┘
par      └────┘ └─────┘
pid            └─────┘
st   ─────────────────┘└─
958      { exact e.elim (eq_zero_of_le_zero (le_of_lt_succ h)) },
id               └────┘  └────────────────┘  └───────────┘ 
src        └────┘└────┘ └────────────────┘ └───────────┘ └─┘
typ        └────┘└────┘ └────────────────┘ └───────────┘└─┘
doc        └────┘                                        └─┘
txt        └────┘                                        └─┘
par        └────┘                                        └─┘
pid                                                     └┘
st   ─────┘└──────────────────────────────────────────────────┘└┘
959      { apply succ_le_succ (IH _),
id               └──────────┘  └┘
src        └────┘└──────────┘   └─┘
typ        └────┘└──────────┘ └┘└─┘
doc        └────┘               └─┘
txt        └────┘               └─┘
par        └────┘               └─┘
pid                            └─┘
st   ──────────────────────────────┘└─
960        apply lt_imp_lt_of_le_imp_le (λ h', bit0_le_bit _ h') h } }
id               └────────────────────┘        └─────────┘       
src        └────┘└────────────────────┘  └───┘└─────────┘└─┘  └┘ 
typ        └────┘└────────────────────┘  └───┘└─────────┘└─┘  └┘
doc        └────┘                        └───┘           └─┘  └┘ 
txt        └────┘                        └───┘           └─┘  └┘ 
par        └────┘                        └───┘           └─┘  └┘ 
pid                                     └───┘           └─┘  └┘ 
st   ─────────────────────────────────────────────────────────────┘└───
961  end⟩
st   ──┘
962  
963  theorem lt_size {m n : ℕ} : m < size n ↔ 2^m ≤ n :=
id                                └──┘      
src                                └──┘       
typ                               └──┘      
964  by rw [← not_lt, iff_not_comm, not_lt, size_le]
id            └────┘  └──────────┘  └────┘  └─────┘
src     └────┘└────┘└┘└──────────┘└┘└────┘└┘└─────┘└─
typ     └────┘└────┘└┘└──────────┘└┘└────┘└┘└─────┘└─
doc     └────┘      └┘            └┘      └┘       └─
txt     └────┘      └┘            └┘      └┘       └─
par     └────┘      └┘            └┘      └┘       └─
pid       └──┘      └┘            └┘      └┘       
st     └───────────┘└────────────┘└──────┘└───────┘
965  
src  
typ  
doc  
txt  
par  
pid  
st   
966  theorem size_pos {n : ℕ} : 0 < size n ↔ 0 < n :=
id                                └──┘      
src                               └──┘      
typ                               └──┘      
967  by rw lt_size; refl
id         └─────┘
src     └─┘└─────┘  └────
typ     └─┘└─────┘  └────
doc     └─┘         └────
txt     └─┘         └────
par     └─┘         └────
pid                    
st     └─────────────────
968  
src  
typ  
doc  
txt  
par  
pid  
st   
969  theorem size_eq_zero {n : ℕ} : size n = 0 ↔ n = 0 :=
id                                 └──┘       
src                                └──┘         
typ                                └──┘       
970  by have := @size_pos n; simp [pos_iff_ne_zero] at this;
id               └──────┘         └─────────────┘
src     └──────┘ └──────┘   └────┘└─────────────┘└───────┘
typ     └──────┘ └──────┘  └────┘└─────────────┘└───────┘
doc     └──────┘            └────┘               └───────┘
txt     └──────┘            └────┘               └───────┘
par     └──────┘            └────┘               └───────┘
pid     └───┘└─┘                               └─────┘
st     └─────────────────────────────────────────────────────
971     exact not_iff_not.1 this
id            └─────────┘   └──┘
src     └────┘└─────────┘└─┘    
typ     └────┘└─────────┘└─┘└──┘
doc     └────┘           └─┘    
txt     └────┘           └─┘    
par     └────┘           └─┘    
pid                     └─┘    
st   ────────────────────────────
972  
src  
typ  
doc  
txt  
par  
pid  
st   
973  theorem size_pow {n : ℕ} : size (2^n) = n+1 :=
id                             └──┘      
src                            └──┘        
typ                            └──┘      
974  le_antisymm
id   └─────────┘
src  └─────────┘
typ  └─────────┘
975    (size_le.2 $ pow_lt_pow_of_lt_right dec_trivial (lt_succ_self _))
id      └─────┘    └────────────────────┘ └─────────┘  └──────────┘
src     └─────┘    └────────────────────┘ └─────────┘  └──────────┘
typ     └─────┘    └────────────────────┘ └─────────┘  └──────────┘
doc                                        └─────────┘
976    (lt_size.2 $ le_refl _)
id      └─────┘    └─────┘
src     └─────┘    └─────┘
typ     └─────┘    └─────┘
977  
978  theorem size_le_size {m n : ℕ} (h : m ≤ n) : size m ≤ size n :=
id                                            └──┘   └──┘ 
src                                             └──┘    └──┘
typ                                           └──┘   └──┘ 
979  size_le.2 $ lt_of_le_of_lt h (lt_size_self _)
id   └─────┘    └────────────┘   └──────────┘
src  └─────┘    └────────────┘    └──────────┘
typ  └─────┘    └────────────┘   └──────────┘
980  
981  /- factorial -/
982  
983  /-- `fact n` is the factorial of `n`. -/
984  @[simp] def fact : nat → nat
id                      └─┘  └─┘
src                     └─┘   └─┘
typ                     └─┘  └─┘
doc    └──┘
985  | 0        := 1
986  | (succ n) := succ n * fact n
id      └──┘      └──┘    └──┘
src     └──┘       └──┘   
typ     └──┘      └──┘    └──┘
987  
988  @[simp] theorem fact_zero : fact 0 = 1 := rfl
id                               └──┘         └─┘
src                              └──┘         └─┘
typ                              └──┘         └─┘
doc    └──┘                      └──┘
989  
990  @[simp] theorem fact_one : fact 1 = 1 := rfl
id                              └──┘         └─┘
src                             └──┘         └─┘
typ                             └──┘         └─┘
doc    └──┘                     └──┘
991  
992  @[simp] theorem fact_succ (n) : fact (succ n) = succ n * fact n := rfl
id                                   └──┘  └──┘    └──┘   └──┘     └─┘
src                                  └──┘  └──┘     └──┘    └──┘      └─┘
typ                                  └──┘  └──┘    └──┘   └──┘     └─┘
doc    └──┘                          └──┘                     └──┘
993  
994  theorem fact_pos : ∀ n, 0 < fact n
id                             └──┘ 
src                             └──┘
typ                            └──┘ 
doc                              └──┘
995  | 0        := zero_lt_one
id                 └─────────┘
src                └─────────┘
typ                └─────────┘
996  | (succ n) := mul_pos (succ_pos _) (fact_pos n)
id      └──┘      └─────┘  └──────┘     └──────┘
src     └──┘       └─────┘  └──────┘
typ     └──┘      └─────┘  └──────┘     └──────┘
997  
998  theorem fact_ne_zero (n : ℕ) : fact n ≠ 0 := ne_of_gt (fact_pos _)
id                                 └──┘        └──────┘  └──────┘
src                                └──┘         └──────┘  └──────┘
typ                                └──┘        └──────┘  └──────┘
doc                                 └──┘
999  
1000  theorem fact_dvd_fact {m n} (h : m ≤ n) : fact m ∣ fact n :=
id                                          └──┘   └──┘ 
src                                           └──┘    └──┘
typ                                         └──┘   └──┘ 
doc                                            └──┘     └──┘
1001  begin
st   └─────
1002    induction n with n IH; simp,
id               
src    └────────┘ └────────┘  └──┘
typ    └────────┘└────────┘  └──┘
doc    └────────┘ └────────┘  └──┘
txt    └────────┘ └────────┘  └──┘
par    └────────┘ └────────┘  └──┘
pid              └───────┘
st   ────────────────────────────┘└─
1003    { have := eq_zero_of_le_zero h, subst m, simp },
id               └────────────────┘         
src      └──────┘└────────────────┘   └────┘   └───┘
typ      └──────┘└────────────────┘  └────┘  └───┘
doc      └──────┘                     └────┘   └───┘
txt      └──────┘                     └────┘   └───┘
par      └──────┘                     └────┘   └───┘
pid      └───┘└─┘                                 
st   ───┘└──────────────────────────┘└───────┘└─────┘└┘
1004    { cases eq_or_lt_of_le h with he hl,
id             └────────────┘ 
src      └────┘└────────────┘ └─────────┘
typ      └────┘└────────────┘└─────────┘
doc      └────┘               └─────────┘
txt      └────┘               └─────────┘
par      └────┘               └─────────┘
pid                          └─────────┘
st   ────────────────────────────────────┘└─
1005      { subst m, simp },
id               
src        └────┘   └───┘
typ        └────┘  └───┘
doc        └────┘   └───┘
txt        └────┘   └───┘
par        └────┘   └───┘
pid                    
st   ─────┘└─────┘└─────┘└┘
1006      { apply dvd_mul_of_dvd_right (IH (le_of_lt_succ hl)) } }
id               └──────────────────┘  └┘  └───────────┘ └┘
src        └────┘└──────────────────┘    └───────────┘  └─┘
typ        └────┘└──────────────────┘ └┘ └───────────┘└┘└─┘
doc        └────┘                                       └─┘
txt        └────┘                                       └─┘
par        └────┘                                       └─┘
pid                                                    └┘
st   ────────────────────────────────────────────────────────┘└───
1007  end
st   ──┘
1008  
1009  theorem dvd_fact : ∀ {m n}, 0 < m → m ≤ n → m ∣ fact n
id                                         └──┘ 
src                                               └──┘
typ                                        └──┘ 
doc                                                  └──┘
1010  | (succ m) n _ h := dvd_of_mul_right_dvd (fact_dvd_fact h)
id      └──┘            └──────────────────┘  └───────────┘
src     └──┘             └──────────────────┘  └───────────┘
typ     └──┘            └──────────────────┘  └───────────┘
1011  
1012  theorem fact_le {m n} (h : m ≤ n) : fact m ≤ fact n :=
id                                    └──┘   └──┘ 
src                                     └──┘    └──┘
typ                                   └──┘   └──┘ 
doc                                      └──┘     └──┘
1013  le_of_dvd (fact_pos _) (fact_dvd_fact h)
id   └───────┘  └──────┘     └───────────┘ 
src  └───────┘  └──────┘     └───────────┘
typ  └───────┘  └──────┘     └───────────┘ 
1014  
1015  lemma fact_mul_pow_le_fact : ∀ {m n : ℕ}, m.fact * m.succ ^ n ≤ (m + n).fact
id                                           └───┘  └───┘        └──┘
src                                            └───┘   └───┘           └──┘
typ                                          └───┘  └───┘        └──┘
doc                                             └───┘                       └──┘
1016  | m 0     := by simp
src                  └───┘
typ                  └───┘
doc                  └───┘
txt                  └───┘
par                  └───┘
pid                      
st                  └────┘
1017  | m (n+1) :=
id         
src        
typ        
1018  by  rw [← add_assoc, nat.fact_succ, mul_comm (nat.succ _), nat.pow_succ, ← mul_assoc];
id             └───────┘  └───────────┘  └──────┘  └──────┘     └──────────┘    └───────┘
src      └────┘└───────┘└┘└───────────┘└┘└──────┘ └──────┘└───┘└──────────┘└──┘└───────┘
typ      └────┘└───────┘└┘└───────────┘└┘└──────┘ └──────┘└───┘└──────────┘└──┘└───────┘
doc      └────┘         └┘             └┘                 └───┘            └──┘         
txt      └────┘         └┘             └┘                 └───┘            └──┘         
par      └────┘         └┘             └┘                 └───┘            └──┘         
pid        └──┘         └┘             └┘                 └───┘            └──┘         
st     └───────────────┘└─────────────┘└─────────────────────┘└────────────┘└───────────┘└─
1019    exact mul_le_mul fact_mul_pow_le_fact
id           └────────┘ └──────────────────┘
src    └────┘└────────┘                    
typ    └────┘└────────┘└──────────────────┘
doc    └────┘                              
txt    └────┘                              
par    └────┘                              
pid                                       
st   ────────────────────────────────────────
1020      (nat.succ_le_succ (nat.le_add_right _ _)) (nat.zero_le _) (nat.zero_le _)
id        └──────────────┘  └──────────────┘                        └─────────┘
src  ───┘ └──────────────┘ └──────────────┘└─────┘            └──┘ └─────────┘└───
typ  ───┘ └──────────────┘ └──────────────┘└─────┘            └──┘ └─────────┘└───
doc  ───┘                                  └─────┘            └──┘            └───
txt  ───┘                                  └─────┘            └──┘            └───
par  ───┘                                  └─────┘            └──┘            └───
pid  ───┘                                  └─────┘            └──┘            └─┘
st   ──────────────────────────────────────────────────────────────────────────────
1021  
src  
typ  
doc  
txt  
par  
pid  
st   
1022  lemma monotone_fact : monotone fact := λ n m, fact_le
id                         └──────┘ └──┘         └─────┘
src                        └──────┘ └──┘           └─────┘
typ                        └──────┘ └──┘         └─────┘
doc                        └──────┘ └──┘
1023  
1024  lemma fact_lt (h0 : 0 < n) : n.fact < m.fact ↔ n < m :=
id                              └───┘  └───┘    
src                               └───┘   └───┘    
typ                             └───┘  └───┘    
doc                                └───┘    └───┘
1025  begin
st   └─────
1026    split; intro h,
src    └───┘  └─────┘
typ    └───┘  └─────┘
doc    └───┘  └─────┘
txt    └───┘  └─────┘
par    └───┘  └─────┘
pid                └┘
st   ───────────────┘└─
1027    { rw [← not_le], intro hmn, apply not_le_of_lt h (fact_le hmn) },
id             └────┘                    └──────────┘   └─────┘ └─┘
src      └────┘└────┘  └───────┘  └────┘└──────────┘  └─────┘   └┘
typ      └────┘└────┘  └───────┘  └────┘└──────────┘ └─────┘└─┘└┘
doc      └────┘        └───────┘  └────┘                        └┘
txt      └────┘        └───────┘  └────┘                        └┘
par      └────┘        └───────┘  └────┘                        └┘
pid        └──┘             └──┘                               
st   ───┘└──────────┘└──────────┘└───────────────────────────────────┘└┘
1028    { have : ∀(n : ℕ), 0 < n → n.fact < n.succ.fact,
id                                └───┘    └───┘└───┘
src      └─────┘ └───┘  └─┘   └───┘  └───┘└───┘
typ      └─────┘ └───┘  └─┘   └───┘  └────────┘
doc      └─────┘ └───┘  └─┘    └───┘       └───┘
txt      └─────┘ └───┘  └─┘          
par      └─────┘ └───┘  └─┘          
pid      └───┘└┘ └───┘  └─┘          
st   ────────────────────────────────────────────────┘└─
1029      { intros k hk, rw [fact_succ, succ_mul, lt_add_iff_pos_left],
id                          └───────┘  └──────┘  └─────────────────┘
src        └─────────┘  └──┘└───────┘└┘└──────┘└┘└─────────────────┘
typ        └─────────┘  └──┘└───────┘└┘└──────┘└┘└─────────────────┘
doc        └─────────┘  └──┘         └┘        └┘                   
txt        └─────────┘  └──┘         └┘        └┘                   
par        └─────────┘  └──┘         └┘        └┘                   
pid              └───┘    └┘         └┘        └┘                   
st   ─────┘└─────────┘└─────────────┘└────────┘└───────────────────┘└──
1030        apply mul_pos hk (fact_pos k) },
id               └─────┘ └┘  └──────┘ 
src        └────┘└─────┘   └──────┘ └┘
typ        └────┘└─────┘└┘ └──────┘└┘
doc        └────┘                   └┘
txt        └────┘                   └┘
par        └────┘                   └┘
pid                                
st   ───────────────────────────────────┘└┘
1031      induction h generalizing h0,
id                 
src      └────────┘ └──────────────┘
typ      └────────┘└──────────────┘
doc      └────────┘ └──────────────┘
txt      └────────┘ └──────────────┘
par      └────────┘ └──────────────┘
pid                └─────────────┘
st   ──────────────────────────────┘└─
1032      { exact this _ h0, },
id               └──┘   └┘
src        └────┘    └─┘
typ        └────┘└──┘└─┘└┘
doc        └────┘    └─┘
txt        └────┘    └─┘
par        └────┘    └─┘
pid                 └─┘
st   ─────┘└─────────────┘└──┘
1033      { refine lt_trans (h_ih h0) (this _ _), exact lt_trans h0 (lt_of_succ_le h_a) }}
id                └──────┘  └──┘ └┘   └──┘             └──────┘ └┘  └───────────┘ └─┘
src        └─────┘└──────┘       └┘     └───┘  └────┘└──────┘   └───────────┘   └┘
typ        └─────┘└──────┘ └──┘└┘└┘ └──┘└───┘  └────┘└──────┘└┘ └───────────┘└─┘└┘
doc        └─────┘               └┘     └───┘  └────┘                           └┘
txt        └─────┘               └┘     └───┘  └────┘                           └┘
par        └─────┘               └┘     └───┘  └────┘                           └┘
pid                             └┘     └───┘                                  
st   ─────────────────────────────────────────┘└──────────────────────────────────────┘└──
1034  end
st   ──┘
1035  
1036  lemma one_lt_fact : 1 < n.fact ↔ 1 < n :=
id                          └───┘     
src                          └───┘    
typ                         └───┘     
doc                           └───┘
1037  by { convert fact_lt _, refl, exact one_pos }
id                └─────┘                └─────┘
src       └──────┘└─────┘└┘  └──┘  └────┘└─────┘
typ       └──────┘└─────┘└┘  └──┘  └────┘└─────┘
doc       └──────┘       └┘  └──┘  └────┘       
txt       └──────┘       └┘  └──┘  └────┘       
par       └──────┘       └┘  └──┘  └────┘       
pid                     └┘                    
st     └──────────────────┘└────┘└──────────────┘└┘
1038  
1039  lemma fact_eq_one : n.fact = 1 ↔ n ≤ 1 :=
id                       └───┘      
src                       └───┘       
typ                      └───┘      
doc                       └───┘
1040  begin
st   └─────
1041    split; intro h,
src    └───┘  └─────┘
typ    └───┘  └─────┘
doc    └───┘  └─────┘
txt    └───┘  └─────┘
par    └───┘  └─────┘
pid                └┘
st   ───────────────┘└─
1042    { rw [← not_lt, ← one_lt_fact, h], apply lt_irrefl },
id             └────┘    └─────────┘           └───────┘
src      └────┘└────┘└──┘└─────────┘└┘   └────┘└───────┘
typ      └────┘└────┘└──┘└─────────┘└┘  └────┘└───────┘
doc      └────┘      └──┘           └┘   └────┘         
txt      └────┘      └──┘           └┘   └────┘         
par      └────┘      └──┘           └┘   └────┘         
pid        └──┘      └──┘           └┘                 
st   ───┘└──────────┘└─────────────┘└─┘└─────────────────┘└┘
1043    { cases h with h h, refl, cases h, refl }
id                                    
src      └────┘ └───────┘  └──┘  └────┘   └───┘
typ      └────┘└───────┘  └──┘  └────┘  └───┘
doc      └────┘ └───────┘  └──┘  └────┘   └───┘
txt      └────┘ └───────┘  └──┘  └────┘   └───┘
par      └────┘ └───────┘  └──┘  └────┘   └───┘
pid            └───────┘                    
st   ───────────────────┘└────┘└───────┘└─────┘└─
1044  end
st   ──┘
1045  
1046  lemma fact_inj (h0 : 1 < n.fact) : n.fact = m.fact ↔ n = m :=
id                           └───┘    └───┘  └───┘    
src                           └───┘     └───┘   └───┘    
typ                          └───┘    └───┘  └───┘    
doc                            └───┘     └───┘    └───┘
1047  begin
st   └─────
1048    split; intro h,
src    └───┘  └─────┘
typ    └───┘  └─────┘
doc    └───┘  └─────┘
txt    └───┘  └─────┘
par    └───┘  └─────┘
pid                └┘
st   ───────────────┘└─
1049    { rcases lt_trichotomy n m with hnm|hnm|hnm,
id              └───────────┘  
src      └─────┘└───────────┘  └───────────────┘
typ      └─────┘└───────────┘└───────────────┘
doc      └─────┘               └───────────────┘
txt      └─────┘               └───────────────┘
par      └─────┘               └───────────────┘
pid                           └───────────────┘
st   ───┘└───────────────────────────────────────┘└─
1050      { exfalso, rw [← fact_lt, h] at hnm, exact lt_irrefl _ hnm,
id                        └─────┘                  └───────┘   └─┘
src        └─────┘  └────┘└─────┘└┘ └──────┘  └────┘└───────┘└─┘
typ        └─────┘  └────┘└─────┘└┘└──────┘  └────┘└───────┘└─┘└─┘
doc        └─────┘  └────┘       └┘ └──────┘  └────┘         └─┘
txt        └─────┘  └────┘       └┘ └──────┘  └────┘         └─┘
par        └─────┘  └────┘       └┘ └──────┘  └────┘         └─┘
pid                   └──┘       └┘ └─────┘                └─┘
st   ─────┘└─────┘└─────────────┘└─┘└─────┘└─────────────────────┘└─
1051        rw [one_lt_fact] at h0, exact lt_trans one_pos h0 },
id             └─────────┘               └──────┘ └─────┘ └┘
src        └──┘└─────────┘└─────┘  └────┘└──────┘└─────┘  
typ        └──┘└─────────┘└─────┘  └────┘└──────┘└─────┘└┘
doc        └──┘           └─────┘  └────┘                 
txt        └──┘           └─────┘  └────┘                 
par        └──┘           └─────┘  └────┘                 
pid          └┘           └────┘                        
st   ────────────────────┘└────┘└──────────────────────────┘└┘
1052      { exact hnm },
id               └─┘
src        └────┘   
typ        └────┘└─┘
doc        └────┘   
txt        └────┘   
par        └────┘   
pid                
st   ─────┘└────────┘└┘
1053      { exfalso, rw [← fact_lt, h] at hnm, exact lt_irrefl _ hnm,
id                        └─────┘                  └───────┘   └─┘
src        └─────┘  └────┘└─────┘└┘ └──────┘  └────┘└───────┘└─┘
typ        └─────┘  └────┘└─────┘└┘└──────┘  └────┘└───────┘└─┘└─┘
doc        └─────┘  └────┘       └┘ └──────┘  └────┘         └─┘
txt        └─────┘  └────┘       └┘ └──────┘  └────┘         └─┘
par        └─────┘  └────┘       └┘ └──────┘  └────┘         └─┘
pid                   └──┘       └┘ └─────┘                └─┘
st   ────────────┘└─────────────┘└─┘└─────┘└─────────────────────┘└─
1054        rw [h, one_lt_fact] at h0, exact lt_trans one_pos h0 }},
id               └─────────┘               └──────┘ └─────┘ └┘
src        └──┘ └┘└─────────┘└─────┘  └────┘└──────┘└─────┘  
typ        └──┘└┘└─────────┘└─────┘  └────┘└──────┘└─────┘└┘
doc        └──┘ └┘           └─────┘  └────┘                 
txt        └──┘ └┘           └─────┘  └────┘                 
par        └──┘ └┘           └─────┘  └────┘                 
pid          └┘ └┘           └────┘                        
st   ──────────┘└───────────┘└────┘└──────────────────────────┘└─┘
1055    { rw h }
id          
src      └─┘ 
typ      └─┘
doc      └─┘ 
txt      └─┘ 
par      └─┘ 
pid         
st   ────────┘└─
1056  end
st   ──┘
1057  
1058  /- choose -/
1059  
1060  /-- `choose n k` is the number of `k`-element subsets in an `n`-element set. Also known as binomial
1061  coefficients. -/
1062  def choose : ℕ → ℕ → ℕ
id                     
src                     
typ                    
1063  | _             0 := 1
1064  | 0       (k + 1) := 0
id                
src               
typ               
1065  | (n + 1) (k + 1) := choose n k + choose n (succ k)
id                    └────┘      └────┘    └──┘
src                                           └──┘
typ                   └────┘      └────┘    └──┘
st                                            
1066  
1067  @[simp] lemma choose_zero_right (n : ℕ) : choose n 0 = 1 := by cases n; refl
id                                            └────┘                   
src                                           └────┘              └────┘   └────
typ                                           └────┘             └────┘  └────
doc    └──┘                                    └────┘               └────┘   └────
txt                                                                 └────┘   └────
par                                                                 └────┘   └────
pid                                                                             
st                                                                 └──────────────
1068  
src  
typ  
doc  
txt  
par  
pid  
st   
1069  @[simp] lemma choose_zero_succ (k : ℕ) : choose 0 (succ k) = 0 := rfl
id                                           └────┘    └──┘         └─┘
src                                          └────┘    └──┘          └─┘
typ                                          └────┘    └──┘         └─┘
doc    └──┘                                   └────┘
1070  
1071  lemma choose_succ_succ (n k : ℕ) : choose (succ n) (succ k) = choose n k + choose n (succ k) := rfl
id                                     └────┘  └──┘    └──┘    └────┘    └────┘   └──┘      └─┘
src                                    └────┘  └──┘     └──┘     └────┘      └────┘    └──┘       └─┘
typ                                    └────┘  └──┘    └──┘    └────┘    └────┘   └──┘      └─┘
doc                                     └────┘                     └────┘       └────┘
1072  
1073  lemma choose_eq_zero_of_lt : ∀ {n k}, n < k → choose n k = 0
id                                           └────┘   
src                                               └────┘     
typ                                          └────┘   
doc                                                └────┘
1074  | _             0 hk := absurd hk dec_trivial
id                     └┘    └────┘    └─────────┘
src                          └────┘    └─────────┘
typ                    └┘    └────┘    └─────────┘
doc                                    └─────────┘
1075  | 0       (k + 1) hk := choose_zero_succ _
id                          └──────────────┘
src                         └──────────────┘
typ                         └──────────────┘
1076  | (n + 1) (k + 1) hk :=
id                 └┘
src              
typ                └┘
1077    have hnk : n < k, from lt_of_succ_lt_succ hk,
id                           └────────────────┘
src                          └────────────────┘
typ                          └────────────────┘
1078    have hnk1 : n < k + 1, from lt_of_succ_lt hk,
id                               └───────────┘
src                              └───────────┘
typ                              └───────────┘
1079    by rw [choose_succ_succ, choose_eq_zero_of_lt hnk, choose_eq_zero_of_lt hnk1]
id            └──────────────┘  └──────────────────┘ └─┘  └──────────────────┘ └──┘
src       └──┘└──────────────┘└┘                       └┘                        └─
typ       └──┘└──────────────┘└┘└──────────────────┘└─┘└┘└──────────────────┘└──┘└─
doc       └──┘                └┘                       └┘                        └─
txt       └──┘                └┘                       └┘                        └─
par       └──┘                └┘                       └┘                        └─
pid         └┘                └┘                       └┘                        
st       └───────────────────┘└────────────────────────┘└─────────────────────────┘
1080  
src  
typ  
doc  
txt  
par  
pid  
st   
1081  @[simp] lemma choose_self (n : ℕ) : choose n n = 1 :=
id                                      └────┘   
src                                     └────┘     
typ                                     └────┘   
doc    └──┘                              └────┘
1082  by induction n; simp [*, choose, choose_eq_zero_of_lt (lt_succ_self _)]
id                           └────┘  └──────────────────┘  └──────────┘
src     └────────┘   └───────┘└────┘└┘└──────────────────┘ └──────────┘└────
typ     └────────┘  └───────┘└────┘└┘└──────────────────┘ └──────────┘└────
doc     └────────┘   └───────┘└────┘└┘                                 └────
txt     └────────┘   └───────┘      └┘                                 └────
par     └────────┘   └───────┘      └┘                                 └────
pid                     └──┘      └┘                                 └──┘
st     └─────────────────────────────────────────────────────────────────────
1083  
src  
typ  
doc  
txt  
par  
pid  
st   
1084  @[simp] lemma choose_succ_self (n : ℕ) : choose n (succ n) = 0 :=
id                                           └────┘   └──┘   
src                                          └────┘    └──┘    
typ                                          └────┘   └──┘   
doc    └──┘                                   └────┘
1085  choose_eq_zero_of_lt (lt_succ_self _)
id   └──────────────────┘  └──────────┘
src  └──────────────────┘  └──────────┘
typ  └──────────────────┘  └──────────┘
1086  
1087  @[simp] lemma choose_one_right (n : ℕ) : choose n 1 = n :=
id                                           └────┘     
src                                          └────┘     
typ                                          └────┘     
doc    └──┘                                   └────┘
1088  by induction n; simp [*, choose]
id                           └────┘
src     └────────┘   └───────┘└────┘└─
typ     └────────┘  └───────┘└────┘└─
doc     └────────┘   └───────┘└────┘└─
txt     └────────┘   └───────┘      └─
par     └────────┘   └───────┘      └─
pid                     └──┘      
st     └──────────────────────────────
1089  
src  
typ  
doc  
txt  
par  
pid  
st   
1090  /-- `choose n 2` is the `n`-th triangle number. -/
1091  lemma choose_two_right (n : ℕ) : choose n 2 = n * (n - 1) / 2 :=
id                                   └────┘             
src                                  └────┘                
typ                                  └────┘             
doc                                   └────┘
1092  by { induction n, simp, simpa [n_ih, choose, add_one] using (triangle_succ n_n).symm }
id                                 └──┘  └────┘  └─────┘         └───────────┘ └─┘
src       └────────┘   └──┘  └─────┘    └┘└────┘└┘└─────┘└──────┘ └───────────┘   └─────┘
typ       └────────┘  └──┘  └─────┘└──┘└┘└────┘└┘└─────┘└──────┘ └───────────┘└─┘└─────┘
doc       └────────┘   └──┘  └─────┘    └┘└────┘└┘       └──────┘                 └─────┘
txt       └────────┘   └──┘  └─────┘    └┘      └┘       └──────┘                 └─────┘
par       └────────┘   └──┘  └─────┘    └┘      └┘       └──────┘                 └─────┘
pid                                  └┘      └┘       └────┘                 └───┘└┘
st     └────────────┘└────┘└─────────────────────────────────────────────────────────────┘└┘
1093  
1094  lemma choose_pos : ∀ {n k}, k ≤ n → 0 < choose n k
id                                    └────┘  
src                                        └────┘
typ                                   └────┘  
doc                                          └────┘
1095  | 0             _ hk := by rw [eq_zero_of_le_zero hk]; exact dec_trivial
id                                  └────────────────┘ └┘         └─────────┘
src                             └──┘└────────────────┘    └────┘└─────────┘
typ                             └──┘└────────────────┘└┘  └────┘└─────────┘
doc                             └──┘                      └────┘└─────────┘
txt                             └──┘                      └────┘           
par                             └──┘                      └────┘           
pid                               └┘                                      
st                             └────────────────────────┘└──────────────────┘
1096  | (n + 1)       0 hk := by simp; exact dec_trivial
id        
src                            └──┘  └────┘           
typ                            └──┘  └────┘           
doc                             └──┘  └────┘           
txt                             └──┘  └────┘           
par                             └──┘  └────┘           
pid                                                   
st                             └───────────────────────┘
1097  | (n + 1) (k + 1) hk := by rw choose_succ_succ;
id                               └──────────────┘
src                           └─┘└──────────────┘
typ                           └─┘└──────────────┘
doc                             └─┘
txt                             └─┘
par                             └─┘
pid                               
st                             └─────────────────────
1098      exact add_pos_of_pos_of_nonneg (choose_pos (le_of_succ_le_succ hk)) (nat.zero_le _)
id             └──────────────────────┘  └────────┘  └────────────────┘ └┘    └─────────┘
src      └────┘└──────────────────────┘            └────────────────┘  └─┘ └─────────┘└───
typ      └────┘└──────────────────────┘ └────────┘ └────────────────┘└┘└─┘ └─────────┘└───
doc      └────┘                                                        └─┘            └───
txt      └────┘                                                        └─┘            └───
par      └────┘                                                        └─┘            └───
pid                                                                   └─┘            └─┘
st   ────────────────────────────────────────────────────────────────────────────────────────
1099  
src  
typ  
doc  
txt  
par  
pid  
st   
1100  lemma succ_mul_choose_eq : ∀ n k, succ n * choose n k = choose (succ n) (succ k) * succ k
id                                   └──┘   └────┘    └────┘  └──┘    └──┘    └──┘ 
src                                    └──┘    └────┘      └────┘  └──┘     └──┘     └──┘
typ                                  └──┘   └────┘    └────┘  └──┘    └──┘    └──┘ 
doc                                             └────┘       └────┘
1101  | 0             0 := dec_trivial
id                        └─────────┘
src                       └─────────┘
typ                       └─────────┘
doc                       └─────────┘
1102  | 0       (k + 1) := by simp [choose]
id                                └────┘
src                         └────┘└────┘└┘
typ                         └────┘└────┘└┘
doc                          └────┘└────┘└┘
txt                          └────┘      └┘
par                          └────┘      └┘
pid                                    
st                          └─────────────┘
1103  | (n + 1)       0 := by simp
id        
src                         └───┘
typ                         └───┘
doc                          └───┘
txt                          └───┘
par                          └───┘
pid                              
st                          └────┘
1104  | (n + 1) (k + 1) :=
id               
src              
typ              
1105    by rw [choose_succ_succ (succ n) (succ k), add_mul, ←succ_mul_choose_eq, mul_succ,
id            └──────────────┘          └──┘    └─────┘   └────────────────┘  └──────┘
src       └──┘└──────────────┘      └┘ └──┘ └─┘└─────┘└─┘                  └┘└──────┘└─
typ       └──┘└──────────────┘     └┘ └──┘└─┘└─────┘└─┘└────────────────┘└┘└──────┘└─
doc       └──┘                      └┘      └─┘       └─┘                  └┘        └─
txt       └──┘                      └┘      └─┘       └─┘                  └┘        └─
par       └──┘                      └┘      └─┘       └─┘                  └┘        └─
pid         └┘                      └┘      └─┘       └─┘                  └┘        └─
st       └─────────────────────────────────────┘└───────┘└───────────────────┘└────────┘└─
1106    ←succ_mul_choose_eq, add_right_comm, ←mul_add, ←choose_succ_succ, ←succ_mul]
id      └────────────────┘  └────────────┘   └─────┘   └──────────────┘   └──────┘
src  ──┘                  └┘└────────────┘└─┘└─────┘└─┘└──────────────┘└─┘└──────┘└─
typ  ──┘└────────────────┘└┘└────────────┘└─┘└─────┘└─┘└──────────────┘└─┘└──────┘└─
doc  ──┘                  └┘              └─┘       └─┘                └─┘        └─
txt  ──┘                  └┘              └─┘       └─┘                └─┘        └─
par  ──┘                  └┘              └─┘       └─┘                └─┘        └─
pid  ──┘                  └┘              └─┘       └─┘                └─┘        
st   ────────────────────┘└──────────────┘└────────┘└─────────────────┘└─────────┘
1107  
src  
typ  
doc  
txt  
par  
pid  
st   
1108  lemma choose_mul_fact_mul_fact : ∀ {n k}, k ≤ n → choose n k * fact k * fact (n - k) = fact n
id                                               └────┘    └──┘   └──┘       └──┘ 
src                                                   └────┘      └──┘    └──┘         └──┘
typ                                              └────┘    └──┘   └──┘       └──┘ 
doc                                                    └────┘       └──┘     └──┘           └──┘
1109  | 0              _ hk := by simp [eq_zero_of_le_zero hk]
id                                     └────────────────┘ └┘
src                              └────┘└────────────────┘  └┘
typ                              └────┘└────────────────┘└┘└┘
doc                              └────┘                    └┘
txt                              └────┘                    └┘
par                              └────┘                    └┘
pid                                                      
st                              └────────────────────────────┘
1110  | (n + 1)        0 hk := by simp
id        
src                             └───┘
typ                             └───┘
doc                              └───┘
txt                              └───┘
par                              └───┘
pid                                  
st                              └────┘
1111  | (n + 1) (succ k) hk :=
id             └──┘
src            └──┘
typ            └──┘
1112  begin
st   └─────
1113    cases lt_or_eq_of_le hk with hk₁ hk₁,
id           └────────────┘ └┘
src    └────┘└────────────┘  └───────────┘
typ    └────┘└────────────┘└┘└───────────┘
doc    └────┘                └───────────┘
txt    └────┘                └───────────┘
par    └────┘                └───────────┘
pid                         └───────────┘
st   ─────────────────────────────────────┘└─
1114    { have h : choose n k * fact (succ k) * fact (n - k) = succ k * fact n :=
id                └────┘                                   └──┘    └──┘ 
src      └───────┘└────┘            └┘        └┘└──┘  └──┘ └───
typ      └───────┘└────┘            └┘        └┘└──┘ └──┘└───
doc      └───────┘└────┘             └┘         └┘       └──┘ └───
txt      └───────┘                   └┘         └┘            └───
par      └───────┘                   └┘         └┘            └───
pid      └────┘└─┘                   └┘         └┘            └───
st   ───┘└───────────────────────────────────────────────────────────────────────
1115        by rw ← choose_mul_fact_mul_fact (le_of_succ_le_succ hk);
id                 └──────────────────────┘  └────────────────┘ └┘
src  ─────┘  └───┘                         └────────────────┘  └─
typ  ─────┘  └───┘└──────────────────────┘ └────────────────┘└┘└─
doc  ─────┘  └───┘                                             └─
txt  ─────┘  └───┘                                             └─
par  ─────┘  └───┘                                             └─
pid  ─────┘  └────┘                                             └──
st   ───────┘└───────────────────────────────────────────────────────
1116        simp [fact_succ, mul_comm, mul_left_comm],
id               └───────┘  └──────┘  └───────────┘
src  ─────┘└────┘└───────┘└┘└──────┘└┘└───────────┘
typ  ─────┘└────┘└───────┘└┘└──────┘└┘└───────────┘
doc  ─────┘└────┘         └┘        └┘             
txt  ─────┘└────┘         └┘        └┘             
par  ─────┘└────┘         └┘        └┘             
pid  ───────────┘         └┘        └┘             
st   ──────────────────────────────────────────────┘└─
1117      have h₁ : fact (n - k) = (n - k) * fact (n - succ k) :=
id                                          └──┘     └──┘ 
src      └────────┘        └┘     └┘ └──┘   └──┘ └────
typ      └────────┘        └┘     └┘ └──┘  └──┘└────
doc      └────────┘        └┘     └┘ └──┘        └────
txt      └────────┘        └┘     └┘             └────
par      └────────┘        └┘     └┘             └────
pid      └─────┘└─┘        └┘     └┘             └───
st   ────────────────────────────────────────────────────────────
1118        by rw [← succ_sub_succ, succ_sub (le_of_lt_succ hk₁), fact_succ],
id                  └───────────┘  └──────┘  └───────────┘ └─┘   └───────┘
src  ─────┘  └────┘└───────────┘└┘└──────┘ └───────────┘   └─┘└───────┘
typ  ─────┘  └────┘└───────────┘└┘└──────┘ └───────────┘└─┘└─┘└───────┘
doc  ─────┘  └────┘             └┘                         └─┘         
txt  ─────┘  └────┘             └┘                         └─┘         
par  ─────┘  └────┘             └┘                         └─┘         
pid  ─────┘  └─────┘             └┘                         └─┘         
st   ───────┘└──────────────────┘└────────────────────────────┘└─────────┘└─
1119      have h₂ : choose n (succ k) * fact (succ k) * ((n - k) * fact (n - succ k)) = (n - k) * fact n :=
id                 └────┘                                                   └──┘                └──┘ 
src      └────────┘└────┘       └┘           └┘      └┘        └──┘ └─┘     └┘ └──┘ └───
typ      └────────┘└────┘       └┘           └┘      └┘        └──┘ └─┘    └┘ └──┘└───
doc      └────────┘└────┘       └┘           └┘      └┘             └─┘     └┘ └──┘ └───
txt      └────────┘             └┘           └┘      └┘             └─┘     └┘      └───
par      └────────┘             └┘           └┘      └┘             └─┘     └┘      └───
pid      └─────┘└─┘             └┘           └┘      └┘             └─┘     └┘      └───
st   ──────────────────────────────────────────────────────────────────────────────────────────────────────
1120        by rw ← choose_mul_fact_mul_fact (le_of_lt_succ hk₁);
id                 └──────────────────────┘  └───────────┘ └─┘
src  ─────┘  └───┘                         └───────────┘   └─
typ  ─────┘  └───┘└──────────────────────┘ └───────────┘└─┘└─
doc  ─────┘  └───┘                                         └─
txt  ─────┘  └───┘                                         └─
par  ─────┘  └───┘                                         └─
pid  ─────┘  └────┘                                         └──
st   ───────┘└───────────────────────────────────────────────────
1121        simp [fact_succ, mul_comm, mul_left_comm, mul_assoc],
id               └───────┘  └──────┘  └───────────┘  └───────┘
src  ─────┘└────┘└───────┘└┘└──────┘└┘└───────────┘└┘└───────┘
typ  ─────┘└────┘└───────┘└┘└──────┘└┘└───────────┘└┘└───────┘
doc  ─────┘└────┘         └┘        └┘             └┘         
txt  ─────┘└────┘         └┘        └┘             └┘         
par  ─────┘└────┘         └┘        └┘             └┘         
pid  ───────────┘         └┘        └┘             └┘         
st   ─────────────────────────────────────────────────────────┘└─
1122      have h₃ : k * fact n ≤ n * fact n := mul_le_mul_right _ (le_of_succ_le_succ hk),
id                                └──┘     └──────────────┘    └────────────────┘ └┘
src      └────────┘         └──┘ └──┘└──────────────┘└─┘ └────────────────┘  
typ      └────────┘        └──┘└──┘└──────────────┘└─┘ └────────────────┘└┘
doc      └────────┘          └──┘ └──┘                └─┘                     
txt      └────────┘               └──┘                └─┘                     
par      └────────┘               └──┘                └─┘                     
pid      └─────┘└─┘               └──┘                └─┘                     
st   ──────────────────────────────────────────────────────────────────────────────────┘└─
1123    rw [choose_succ_succ, add_mul, add_mul, succ_sub_succ, h, h₁, h₂, ← add_one, add_mul, nat.mul_sub_right_distrib,
id         └──────────────┘  └─────┘  └─────┘  └───────────┘    └┘  └┘    └─────┘  └─────┘  └───────────────────────┘
src    └──┘└──────────────┘└┘└─────┘└┘└─────┘└┘└───────────┘└┘ └┘  └┘  └──┘└─────┘└┘└─────┘└┘└───────────────────────┘└─
typ    └──┘└──────────────┘└┘└─────┘└┘└─────┘└┘└───────────┘└┘└┘└┘└┘└┘└──┘└─────┘└┘└─────┘└┘└───────────────────────┘└─
doc    └──┘                └┘       └┘       └┘             └┘ └┘  └┘  └──┘       └┘       └┘                         └─
txt    └──┘                └┘       └┘       └┘             └┘ └┘  └┘  └──┘       └┘       └┘                         └─
par    └──┘                └┘       └┘       └┘             └┘ └┘  └┘  └──┘       └┘       └┘                         └─
pid      └┘                └┘       └┘       └┘             └┘ └┘  └┘  └──┘       └┘       └┘                         └─
st   ─────────────────────┘└───────┘└───────┘└─────────────┘└─┘└──┘└──┘└─────────┘└───────┘└─────────────────────────┘└─
1124        fact_succ, ← nat.add_sub_assoc h₃, add_assoc, ← add_mul, nat.add_sub_cancel_left, add_comm] },
id         └───────┘    └───────────────┘ └┘  └───────┘    └─────┘  └─────────────────────┘  └──────┘
src  ─────┘└───────┘└──┘└───────────────┘  └┘└───────┘└──┘└─────┘└┘└─────────────────────┘└┘└──────┘└┘
typ  ─────┘└───────┘└──┘└───────────────┘└┘└┘└───────┘└──┘└─────┘└┘└─────────────────────┘└┘└──────┘└┘
doc  ─────┘         └──┘                   └┘         └──┘       └┘                       └┘        └┘
txt  ─────┘         └──┘                   └┘         └──┘       └┘                       └┘        └┘
par  ─────┘         └──┘                   └┘         └──┘       └┘                       └┘        └┘
pid  ─────┘         └──┘                   └┘         └──┘       └┘                       └┘        
st   ──────────────┘└──────────────────────┘└─────────┘└─────────┘└───────────────────────┘└────────┘└┘
1125    { simp [hk₁, mul_comm, choose, nat.sub_self] }
id             └─┘  └──────┘  └────┘  └──────────┘
src      └────┘   └┘└──────┘└┘└────┘└┘└──────────┘└┘
typ      └────┘└─┘└┘└──────┘└┘└────┘└┘└──────────┘└┘
doc      └────┘   └┘        └┘└────┘└┘            └┘
txt      └────┘   └┘        └┘      └┘            └┘
par      └────┘   └┘        └┘      └┘            └┘
pid             └┘        └┘      └┘            
st   ──────────────────────────────────────────────┘└─
1126  end
st   ──┘
1127  
1128  theorem choose_eq_fact_div_fact {n k : ℕ} (hk : k ≤ n) : choose n k = fact n / (fact k * fact (n - k)) :=
id                                                        └────┘    └──┘    └──┘   └──┘    
src                                                         └────┘      └──┘     └──┘    └──┘    
typ                                                       └────┘    └──┘    └──┘   └──┘    
doc                                                           └────┘       └──┘      └──┘     └──┘
1129  begin
st   └─────
1130    have : fact n = choose n k * (fact k * fact (n - k)) :=
id                    └────┘                └──┘    
src    └─────┘     └────┘         └──┘   └─────
typ    └─────┘     └────┘         └──┘ └─────
doc    └─────┘      └────┘          └──┘    └─────
txt    └─────┘                              └─────
par    └─────┘                              └─────
pid    └───┘└┘                              └┘└───
st   ──────────────────────────────────────────────────────────
1131      by rw ← mul_assoc; exact (choose_mul_fact_mul_fact hk).symm,
id               └───────┘         └──────────────────────┘ └┘
src  ───┘  └───┘└───────┘└┘└────┘ └──────────────────────┘  └────┘
typ  ───┘  └───┘└───────┘└┘└────┘ └──────────────────────┘└┘└────┘
doc  ───┘  └───┘         └┘└────┘                           └────┘
txt  ───┘  └───┘         └┘└────┘                           └────┘
par  ───┘  └───┘         └┘└────┘                           └────┘
pid  ───┘  └────┘         └──────┘                           └────┘
st   ─────┘└───────────────────────────────────────────────────────┘└─
1132    exact (nat.div_eq_of_eq_mul_left (mul_pos (fact_pos _) (fact_pos _)) this).symm
id            └───────────────────────┘  └─────┘               └──────┘     └──┘
src    └────┘ └───────────────────────┘ └─────┘         └──┘ └──────┘└───┘    └─────┘
typ    └────┘ └───────────────────────┘ └─────┘         └──┘ └──────┘└───┘└──┘└─────┘
doc    └────┘                                           └──┘         └───┘    └─────┘
txt    └────┘                                           └──┘         └───┘    └─────┘
par    └────┘                                           └──┘         └───┘    └─────┘
pid                                                    └──┘         └───┘    └───┘└┘
st   ─────────────────────────────────────────────────────────────────────────────────┘
1133  end
st   └─┘
1134  
1135  theorem fact_mul_fact_dvd_fact {n k : ℕ} (hk : k ≤ n) : fact k * fact (n - k) ∣ fact n :=
id                                                       └──┘   └──┘       └──┘ 
src                                                        └──┘    └──┘         └──┘
typ                                                      └──┘   └──┘       └──┘ 
doc                                                          └──┘     └──┘           └──┘
1136  by rw [←choose_mul_fact_mul_fact hk, mul_assoc]; exact dvd_mul_left _ _
id           └──────────────────────┘ └┘  └───────┘         └──────────┘
src     └───┘└──────────────────────┘  └┘└───────┘  └────┘└──────────┘└────
typ     └───┘└──────────────────────┘└┘└┘└───────┘  └────┘└──────────┘└────
doc     └───┘                          └┘           └────┘            └────
txt     └───┘                          └┘           └────┘            └────
par     └───┘                          └┘           └────┘            └────
pid       └─┘                          └┘                            └──┘
st     └───────────────────────────────┘└─────────┘└────────────────────────
1137  
src  
typ  
doc  
txt  
par  
pid  
st   
1138  @[simp] lemma choose_symm {n k : ℕ} (hk : k ≤ n) : choose n (n-k) = choose n k :=
id                                                  └────┘      └────┘  
src                                                   └────┘         └────┘
typ                                                 └────┘      └────┘  
doc    └──┘                                             └────┘           └────┘
1139  by rw [choose_eq_fact_div_fact hk, choose_eq_fact_div_fact (sub_le _ _), nat.sub_sub_self hk, mul_comm]
id          └─────────────────────┘ └┘  └─────────────────────┘  └────┘       └──────────────┘ └┘  └──────┘
src     └──┘└─────────────────────┘  └┘└─────────────────────┘ └────┘└─────┘└──────────────┘  └┘└──────┘└─
typ     └──┘└─────────────────────┘└┘└┘└─────────────────────┘ └────┘└─────┘└──────────────┘└┘└┘└──────┘└─
doc     └──┘                         └┘                              └─────┘                  └┘        └─
txt     └──┘                         └┘                              └─────┘                  └┘        └─
par     └──┘                         └┘                              └─────┘                  └┘        └─
pid       └┘                         └┘                              └─────┘                  └┘        
st     └─────────────────────────────┘└────────────────────────────────────┘└───────────────────┘└────────┘
1140  
src  
typ  
doc  
txt  
par  
pid  
st   
1141  lemma choose_succ_right_eq (n k : ℕ) : choose n (k + 1) * (k + 1) = choose n k * (n - k) :=
id                                         └────┘                └────┘       
src                                        └────┘                   └────┘         
typ                                        └────┘                └────┘       
doc                                         └────┘                       └────┘
1142  begin
st   └─────
1143    have e : (n+1) * choose n k = choose n k * (k+1) + choose n (k+1) * (k+1),
id                                                     └────┘           
src    └───────┘  └─┘                    └─┘ └────┘    └─┘    └┘
typ    └───────┘  └─┘                    └─┘ └────┘   └─┘   └┘
doc    └───────┘   └─┘                      └─┘ └────┘    └─┘    └┘
txt    └───────┘   └─┘                      └─┘           └─┘    └┘
par    └───────┘   └─┘                      └─┘           └─┘    └┘
pid    └────┘└─┘   └─┘                      └─┘           └─┘    └┘
st   ──────────────────────────────────────────────────────────────────────────┘└─
1144      rw [← right_distrib, ← choose_succ_succ, succ_mul_choose_eq],
id             └───────────┘    └──────────────┘  └────────────────┘
src      └────┘└───────────┘└──┘└──────────────┘└┘└────────────────┘
typ      └────┘└───────────┘└──┘└──────────────┘└┘└────────────────┘
doc      └────┘             └──┘                └┘                  
txt      └────┘             └──┘                └┘                  
par      └────┘             └──┘                └┘                  
pid        └──┘             └──┘                └┘                  
st   ──────────────────────┘└──────────────────┘└──────────────────┘└──
1145    rw [← nat.sub_eq_of_eq_add e, mul_comm, ← nat.mul_sub_left_distrib, nat.add_sub_add_right]
id           └──────────────────┘   └──────┘    └──────────────────────┘  └───────────────────┘
src    └────┘└──────────────────┘ └┘└──────┘└──┘└──────────────────────┘└┘└───────────────────┘└┘
typ    └────┘└──────────────────┘└┘└──────┘└──┘└──────────────────────┘└┘└───────────────────┘└┘
doc    └────┘                     └┘        └──┘                        └┘                     └┘
txt    └────┘                     └┘        └──┘                        └┘                     └┘
par    └────┘                     └┘        └──┘                        └┘                     └┘
pid      └──┘                     └┘        └──┘                        └┘                     
st   ─────────────────────────────┘└────────┘└──────────────────────────┘└─────────────────────┘
1146  end
st   └─┘
1147  
1148  @[simp] lemma choose_succ_self_right : ∀ (n:ℕ), (n+1).choose n = n+1
id                                                    └────┘    
src                                                     └────┘      
typ                                                   └────┘    
doc    └──┘                                               └────┘
1149  | 0     := rfl
id              └─┘
src             └─┘
typ             └─┘
1150  | (n+1) := by rw [choose_succ_succ, choose_succ_self_right, choose_self]
id                    └──────────────┘  └────────────────────┘  └─────────┘
src               └──┘└──────────────┘└┘                      └┘└─────────┘└─
typ               └──┘└──────────────┘└┘└────────────────────┘└┘└─────────┘└─
doc                └──┘                └┘                      └┘           └─
txt                └──┘                └┘                      └┘           └─
par                └──┘                └┘                      └┘           └─
pid                  └┘                └┘                      └┘           
st                └───────────────────┘└──────────────────────┘└───────────┘
1151  
src  
typ  
doc  
txt  
par  
pid  
st   
1152  lemma choose_mul_succ_eq (n k : ℕ) :
id                                   
src                                  
typ                                  
1153    (n.choose k) * (n + 1) = ((n+1).choose k) * (n + 1 - k) :=
id      └─────┘               └────┘           
src      └─────┘                  └────┘            
typ     └─────┘               └────┘           
doc      └─────┘                      └────┘
1154  begin
st   └─────
1155    induction k with k ih, { simp },
id               
src    └────────┘ └────────┘    └───┘
typ    └────────┘└────────┘    └───┘
doc    └────────┘ └────────┘    └───┘
txt    └────────┘ └────────┘    └───┘
par    └────────┘ └────────┘    └───┘
pid              └───────┘        
st   ──────────────────────┘└──┘└───┘└┘
1156    by_cases hk : n < k + 1,
id                      
src    └───────┘  └─┘  └┘
typ    └───────┘  └─┘└┘
doc    └───────┘  └─┘    └┘
txt    └───────┘  └─┘    └┘
par    └───────┘  └─┘    └┘
pid              └─┘    
st   ────────────────────────┘└─
1157    { rw [choose_eq_zero_of_lt hk, sub_eq_zero_of_le hk, zero_mul, mul_zero] },
id           └──────────────────┘ └┘  └───────────────┘ └┘  └──────┘  └──────┘
src      └──┘└──────────────────┘  └┘└───────────────┘  └┘└──────┘└┘└──────┘└┘
typ      └──┘└──────────────────┘└┘└┘└───────────────┘└┘└┘└──────┘└┘└──────┘└┘
doc      └──┘                      └┘                   └┘        └┘        └┘
txt      └──┘                      └┘                   └┘        └┘        └┘
par      └──┘                      └┘                   └┘        └┘        └┘
pid        └┘                      └┘                   └┘        └┘        
st   ───┘└─────────────────────────┘└────────────────────┘└────────┘└────────┘└┘
1158    push_neg at hk,
src    └────────────┘
typ    └────────────┘
doc    └────────────┘
txt    └────────────┘
par    └────────────┘
pid            └────┘
st   ───────────────┘└─
1159    replace hk : k + 1 ≤ n + 1 := _root_.le_add_right hk,
id                                 └─────────────────┘ └┘
src    └───────────┘  └─┘   └────┘└─────────────────┘
typ    └───────────┘ └─┘  └────┘└─────────────────┘└┘
doc    └───────────┘  └─┘   └────┘                   
txt    └───────────┘  └─┘   └────┘                   
par    └───────────┘  └─┘   └────┘                   
pid           └─┘└─┘  └─┘   └───┘                   
st   ─────────────────────────────────────────────────────┘└─
1160    rw [choose_succ_succ],
id         └──────────────┘
src    └──┘└──────────────┘
typ    └──┘└──────────────┘
doc    └──┘                
txt    └──┘                
par    └──┘                
pid      └┘                
st   ─────────────────────┘└──
1161    rw [add_mul, succ_sub_succ],
id         └─────┘  └───────────┘
src    └──┘└─────┘└┘└───────────┘
typ    └──┘└─────┘└┘└───────────┘
doc    └──┘       └┘             
txt    └──┘       └┘             
par    └──┘       └┘             
pid      └┘       └┘             
st   ────────────┘└─────────────┘└──
1162    rw [← choose_succ_right_eq],
id           └──────────────────┘
src    └────┘└──────────────────┘
typ    └────┘└──────────────────┘
doc    └────┘                    
txt    └────┘                    
par    └────┘                    
pid      └──┘                    
st   ───────────────────────────┘└──
1163    rw [← succ_sub_succ, nat.mul_sub_left_distrib],
id           └───────────┘  └──────────────────────┘
src    └────┘└───────────┘└┘└──────────────────────┘
typ    └────┘└───────────┘└┘└──────────────────────┘
doc    └────┘             └┘                        
txt    └────┘             └┘                        
par    └────┘             └┘                        
pid      └──┘             └┘                        
st   ────────────────────┘└────────────────────────┘└──
1164    symmetry,
src    └──────┘
typ    └──────┘
doc    └──────┘
txt    └──────┘
par    └──────┘
st   ─────────┘└─
1165    apply nat.add_sub_cancel',
id           └─────────────────┘
src    └────┘└─────────────────┘
typ    └────┘└─────────────────┘
doc    └────┘
txt    └────┘
par    └────┘
pid         
st   ──────────────────────────┘└─
1166    exact mul_le_mul_left _ hk,
id           └─────────────┘   └┘
src    └────┘└─────────────┘└─┘
typ    └────┘└─────────────┘└─┘└┘
doc    └────┘               └─┘
txt    └────┘               └─┘
par    └────┘               └─┘
pid                        └─┘
st   ───────────────────────────┘└─
1167  end
st   ──┘
1168  
1169  section find_greatest
1170  
1171  /-- `find_greatest P b` is the largest `i ≤ bound` such that `P i` holds, or `0` if no such `i`
1172  exists -/
1173  protected def find_greatest (P : ℕ → Prop) [decidable_pred P] : ℕ → ℕ
id                                              └────────────┘       
src                                             └────────────┘         
typ                                             └────────────┘       
1174  | 0       := 0
1175  | (n + 1) := if P (n + 1) then n + 1 else find_greatest n
id                                        └───────────┘
src                                 
typ                                       └───────────┘
1176  
1177  variables {P : ℕ → Prop} [decidable_pred P]
id                           └────────────┘
src                           └────────────┘
typ                          └────────────┘
1178  
1179  @[simp] lemma find_greatest_zero : nat.find_greatest P 0 = 0 := rfl
id                                      └───────────────┘          └─┘
src                                     └───────────────┘           └─┘
typ                                     └───────────────┘          └─┘
doc    └──┘                             └───────────────┘
1180  
1181  @[simp] lemma find_greatest_eq : ∀{b}, P b → nat.find_greatest P b = b
id                                            └───────────────┘    
src                                               └───────────────┘     
typ                                           └───────────────┘    
doc    └──┘                                       └───────────────┘
1182  | 0       h := rfl
id                  └─┘
src                 └─┘
typ                 └─┘
1183  | (n + 1) h := by simp [nat.find_greatest, h]
id                          └───────────────┘  
src                   └────┘└───────────────┘└┘ └─
typ                   └────┘└───────────────┘└┘└─
doc                    └────┘└───────────────┘└┘ └─
txt                    └────┘                 └┘ └─
par                    └────┘                 └┘ └─
pid                                         └┘ 
st                    └────────────────────────────
1184  
src  
typ  
doc  
txt  
par  
pid  
st   
1185  @[simp] lemma find_greatest_of_not {b} (h : ¬ P (b + 1)) :
id                                                   
src                                                    
typ                                                  
doc    └──┘
1186    nat.find_greatest P (b + 1) = nat.find_greatest P b :=
id     └───────────────┘         └───────────────┘  
src    └───────────────┘           └───────────────┘
typ    └───────────────┘         └───────────────┘  
doc    └───────────────┘             └───────────────┘
1187  by simp [nat.find_greatest, h]
id            └───────────────┘  
src     └────┘└───────────────┘└┘ └─
typ     └────┘└───────────────┘└┘└─
doc     └────┘└───────────────┘└┘ └─
txt     └────┘                 └┘ └─
par     └────┘                 └┘ └─
pid                          └┘ 
st     └────────────────────────────
1188  
src  
typ  
doc  
txt  
par  
pid  
st   
1189  lemma find_greatest_spec_and_le :
1190    ∀{b m}, m ≤ b → P m → P (nat.find_greatest P b) ∧ m ≤ nat.find_greatest P b
id                     └───────────────┘       └───────────────┘  
src                            └───────────────┘          └───────────────┘
typ                    └───────────────┘       └───────────────┘  
doc                             └───────────────┘            └───────────────┘
1191  | 0       m hm hP :=
id              └┘ └┘
typ             └┘ └┘
1192    have m = 0, from le_antisymm hm (nat.zero_le _),
id                     └─────────┘     └─────────┘
src                    └─────────┘     └─────────┘
typ                    └─────────┘     └─────────┘
1193    show P 0 ∧ m ≤ 0, from this ▸ ⟨hP, le_refl _⟩
id                         └──┘       └─────┘
src                                    └─────┘
typ                        └──┘       └─────┘
1194  | (b + 1) m hm hP :=
id        
src       
typ       
1195    begin
st     └─────
1196      by_cases h : P (b + 1),
id                       
src      └───────┘ └─┘   └─┘
typ      └───────┘ └─┘ └─┘
doc      └───────┘ └─┘    └─┘
txt      └───────┘ └─┘    └─┘
par      └───────┘ └─┘    └─┘
pid               └─┘    └─┘
st   ─────────────────────────┘└─
1197      { simp [h, hm] },
id                 └┘
src        └────┘ └┘  └┘
typ        └────┘└┘└┘└┘
doc        └────┘ └┘  └┘
txt        └────┘ └┘  └┘
par        └────┘ └┘  └┘
pid             └┘  
st   ─────┘└───────────┘└┘
1198      { have : m ≠ b + 1 := assume this, h $ this ▸ hP,
id                                                └┘
src        └─────┘   └────┘      └─────┘      
typ        └─────┘ └────┘      └─────┘     └┘
doc        └─────┘    └────┘      └─────┘       
txt        └─────┘    └────┘      └─────┘       
par        └─────┘    └────┘      └─────┘       
pid        └───┘└┘    └───┘      └─────┘       
st   ───────────────────────────────────────────────────┘└─
1199        have : m ≤ b := (le_of_not_gt $ assume h : b + 1 ≤ m, this $ le_antisymm hm h),
id                       └──────────┘                      └──┘   └─────────┘ └┘
src        └─────┘  └──┘ └──────────┘       └───┘  └─┘  └┘     └─────────┘   
typ        └─────┘└──┘ └──────────┘       └───┘ └─┘└┘└──┘ └─────────┘└┘ 
doc        └─────┘   └──┘                    └───┘  └─┘  └┘                   
txt        └─────┘   └──┘                    └───┘  └─┘  └┘                   
par        └─────┘   └──┘                    └───┘  └─┘  └┘                   
pid        └───┘└┘   └──┘                    └───┘  └─┘  └┘                   
st   ───────────────────────────────────────────────────────────────────────────────────┘└─
1200        have : P (nat.find_greatest P b) ∧ m ≤ nat.find_greatest P b :=
id                                               └───────────────┘  
src        └─────┘                     └┘   └───────────────┘  └───
typ        └─────┘                     └┘  └───────────────┘└───
doc        └─────┘                     └┘   └───────────────┘  └───
txt        └─────┘                     └┘                      └───
par        └─────┘                     └┘                      └───
pid        └───┘└┘                     └┘                      └───
st   ──────────────────────────────────────────────────────────────────────
1201          find_greatest_spec_and_le this hP,
id           └───────────────────────┘ └──┘ └┘
src  ───────┘                             
typ  ───────┘└───────────────────────┘└──┘└┘
doc  ───────┘                             
txt  ───────┘                             
par  ───────┘                             
pid  ───────┘                             
st   ────────────────────────────────────────┘└─
1202        simp [h, this] }
id                 └──┘
src        └────┘ └┘    └┘
typ        └────┘└┘└──┘└┘
doc        └────┘ └┘    └┘
txt        └────┘ └┘    └┘
par        └────┘ └┘    └┘
pid             └┘    
st   ────────────────────┘└─
1203    end
st   ────┘
1204  
1205  lemma find_greatest_spec {b} : (∃m, m ≤ b ∧ P m) → P (nat.find_greatest P b)
id                                              └───────────────┘  
src                                                    └───────────────┘
typ                                             └───────────────┘  
doc                                                        └───────────────┘
1206  | ⟨m, hmb, hm⟩ := (find_greatest_spec_and_le hmb hm).1
id         └─┘  └┘      └───────────────────────┘        
src                     └───────────────────────┘        
typ        └─┘  └┘      └───────────────────────┘        
1207  
1208  lemma find_greatest_le : ∀ {b}, nat.find_greatest P b ≤ b
id                                 └───────────────┘    
src                                  └───────────────┘     
typ                                └───────────────┘    
doc                                  └───────────────┘
1209  | 0       := le_refl _
id                └─────┘
src               └─────┘
typ               └─────┘
1210  | (b + 1) :=
id       
src       
typ      
1211    have nat.find_greatest P b ≤ b + 1, from le_trans find_greatest_le (nat.le_succ b),
id          └───────────────┘                └──────┘ └──────────────┘  └─────────┘
src         └───────────────┘                 └──────┘                   └─────────┘
typ         └───────────────┘                └──────┘ └──────────────┘  └─────────┘
doc         └───────────────┘
1212    by by_cases P (b + 1); simp [h, this]
id                                 └──┘
src       └───────┘   └─┘  └────┘ └┘    └─
typ       └───────┘ └─┘  └────┘└┘└──┘└─
doc       └───────┘    └─┘  └────┘ └┘    └─
txt       └───────┘    └─┘  └────┘ └┘    └─
par       └───────┘    └─┘  └────┘ └┘    └─
pid                   └─┘       └┘    
st       └───────────────────────────────────
1213  
src  
typ  
doc  
txt  
par  
pid  
st   
1214  lemma le_find_greatest {b m} (hmb : m ≤ b) (hm : P m) : m ≤ nat.find_greatest P b :=
id                                                        └───────────────┘  
src                                                            └───────────────┘
typ                                                       └───────────────┘  
doc                                                              └───────────────┘
1215  (find_greatest_spec_and_le hmb hm).2
id    └───────────────────────┘ └─┘ └┘ 
src   └───────────────────────┘        
typ   └───────────────────────┘ └─┘ └┘ 
1216  
1217  lemma find_greatest_is_greatest {P : ℕ → Prop} [decidable_pred P] {b} :
id                                                  └────────────┘ 
src                                                 └────────────┘
typ                                                 └────────────┘ 
1218    (∃ m, m ≤ b ∧ P m) → ∀ k, nat.find_greatest P b < k ∧ k ≤ b → ¬ P k
id                    └───────────────┘             
src                          └───────────────┘                
typ                   └───────────────┘             
doc                              └───────────────┘
1219  | ⟨m, hmb, hP⟩ k ⟨hk, hkb⟩ hPk := lt_irrefl k $ lt_of_le_of_lt (le_find_greatest hkb hPk) hk
id                    └┘  └─┘  └─┘    └───────┘     └────────────┘  └──────────────┘
src                                    └───────┘     └────────────┘  └──────────────┘
typ                   └┘  └─┘  └─┘    └───────┘     └────────────┘  └──────────────┘
1220  
1221  lemma find_greatest_eq_zero {P : ℕ → Prop} [decidable_pred P] :
id                                              └────────────┘ 
src                                             └────────────┘
typ                                             └────────────┘ 
1222    ∀ {b}, (∀ n ≤ b, ¬ P n) → nat.find_greatest P b = 0
id                        └───────────────┘   
src                             └───────────────┘     
typ                       └───────────────┘   
doc                              └───────────────┘
1223  | 0       h := find_greatest_zero
id                  └────────────────┘
src                 └────────────────┘
typ                 └────────────────┘
1224  | (n + 1) h :=
id        
src       
typ       
1225  begin
st   └─────
1226    have := nat.find_greatest_of_not (h (n + 1) (le_refl _)),
id             └──────────────────────┘          └─────┘
src    └──────┘└──────────────────────┘    └──┘ └─────┘└──┘
typ    └──────┘└──────────────────────┘  └──┘ └─────┘└──┘
doc    └──────┘                             └──┘        └──┘
txt    └──────┘                             └──┘        └──┘
par    └──────┘                             └──┘        └──┘
pid    └───┘└─┘                             └──┘        └──┘
st   ─────────────────────────────────────────────────────────┘└─
1227    rw this, exact find_greatest_eq_zero (assume k hk, h k (le_trans hk $ nat.le_succ _))
id        └──┘        └───────────────────┘                   └──────┘      └─────────┘
src    └─┘      └────┘                            └─────┘   └──────┘   └─────────┘└───┘
typ    └─┘└──┘  └────┘└───────────────────┘       └─────┘  └──────┘   └─────────┘└───┘
doc    └─┘      └────┘                            └─────┘                         └───┘
txt    └─┘      └────┘                            └─────┘                         └───┘
par    └─┘      └────┘                            └─────┘                         └───┘
pid                                             └─────┘                         └──┘
st   ────────┘└─────────────────────────────────────────────────────────────────────────────┘
1228  end
st   └─┘
1229  
1230  lemma find_greatest_of_ne_zero {P : ℕ → Prop} [decidable_pred P] :
id                                                 └────────────┘ 
src                                                └────────────┘
typ                                                └────────────┘ 
1231    ∀ {b m}, nat.find_greatest P b = m → m ≠ 0 → P m
id           └───────────────┘              
src             └───────────────┘            
typ          └───────────────┘              
doc             └───────────────┘
1232  | 0       m rfl h := by { have := @find_greatest_zero P _, contradiction }
id               └─┘                    └────────────────┘ 
src              └─┘           └──────┘ └────────────────┘ └┘  └────────────┘
typ              └─┘           └──────┘ └────────────────┘└┘  └────────────┘
doc                            └──────┘                    └┘  └────────────┘
txt                            └──────┘                    └┘  └────────────┘
par                            └──────┘                    └┘  └────────────┘
pid                            └───┘└─┘                    └┘               
st                          └────────────────────────────────┘└──────────────┘└┘
1233  | (b + 1) m rfl h :=
id             └─┘ 
src             └─┘
typ            └─┘ 
1234  decidable.by_cases
id   └────────────────┘
src  └────────────────┘
typ  └────────────────┘
1235    (assume hb : P (b + 1), by { have := find_greatest_eq hb, rw this, exact hb })
id                                        └──────────────┘ └┘     └──┘        └┘
src                                └──────┘└──────────────┘    └─┘      └────┘  
typ                               └──────┘└──────────────┘└┘  └─┘└──┘  └────┘└┘
doc                                 └──────┘                    └─┘      └────┘  
txt                                 └──────┘                    └─┘      └────┘  
par                                 └──────┘                    └─┘      └────┘  
pid                                 └───┘└─┘                                   
st                               └────────────────────────────┘└───────┘└─────────┘└┘
1236    (assume hb : ¬ P (b + 1), find_greatest_of_ne_zero (find_greatest_of_not hb).symm h)
id                            └──────────────────────┘  └──────────────────┘ └┘ └──┘
src                                                      └──────────────────┘    └──┘
typ                           └──────────────────────┘  └──────────────────┘ └┘ └──┘
1237  
1238  end find_greatest
1239  
1240  section div
1241  lemma dvd_div_of_mul_dvd {a b c : ℕ} (h : a * b ∣ c) : b ∣ c / a :=
id                                                        
src                                                           
typ                                                       
1242  if ha : a = 0 then
id   └┘       
src  └┘        
typ  └┘       
1243    by simp [ha]
id              └┘
src       └────┘  └┘
typ       └────┘└┘└┘
doc       └────┘  └┘
txt       └────┘  └┘
par       └────┘  └┘
pid             
st       └─────────┘
1244  else
1245    have ha : 0 < a, from nat.pos_of_ne_zero ha,
id     └──┘                └────────────────┘ └┘
src                         └────────────────┘
typ    └──┘                └────────────────┘ └┘
1246    have h1 : ∃ d, c = a * b * d, from h,
id                              
src                         
typ                             
1247    let ⟨d, hd⟩ := h1 in
id     └─┘           └┘
typ    └─┘           └┘
1248    have hac : a ∣ c, from dvd_of_mul_right_dvd h,
id                         └──────────────────┘ 
src                          └──────────────────┘
typ                        └──────────────────┘ 
1249    have h2 : c / a = b * d, from nat.div_eq_of_eq_mul_right ha (by simpa [mul_assoc] using hd),
id                             └────────────────────────┘ └┘            └───────┘        └┘
src                               └────────────────────────┘        └─────┘└───────┘└──────┘
typ                            └────────────────────────┘ └┘     └─────┘└───────┘└──────┘└┘
doc                                                                    └─────┘         └──────┘
txt                                                                    └─────┘         └──────┘
par                                                                    └─────┘         └──────┘
pid                                                                                  └────┘
st                                                                    └─────────────────────────┘
1250    show ∃ d, c / a = b * d, from ⟨d, h2⟩
id                             └┘
src                    
typ                            └┘
1251  
1252  lemma mul_dvd_of_dvd_div {a b c : ℕ} (hab : c ∣ b) (h : a ∣ b / c) : c * a ∣ b :=
id                                                                   
src                                                                        
typ                                                                  
1253  have h1 : ∃ d, b / c = a * d, from h,
id                            
src                       
typ                           
1254  have h2 : ∃ e, b = c * e, from hab,
id                          └─┘
src                    
typ                         └─┘
1255  let ⟨d, hd⟩ := h1, ⟨e, he⟩ := h2 in
id   └─┘    └┘     └┘             └┘
typ  └─┘    └┘     └┘             └┘
1256  have h3 : b = a * d * c, from
id                    
src                    
typ                   
1257    nat.eq_mul_of_div_eq_left hab hd,
id     └───────────────────────┘ └─┘
src    └───────────────────────┘
typ    └───────────────────────┘ └─┘
1258  show ∃ d, b = c * a * d, from ⟨d, by cc⟩
id                
src                                  └┘
typ                             └┘
doc                                       └┘
txt                                       └┘
par                                       └┘
st                                       └─┘
1259  
1260  lemma div_mul_div {a b c d : ℕ} (hab : b ∣ a) (hcd : d ∣ c) :
id                                                      
src                                                       
typ                                                     
1261        (a / b) * (c / d) = (a * c) / (b * d) :=
id                              
src                                   
typ                             
1262  have exi1 : ∃ x, a = b * x, from hab,
id                            └─┘
src                      
typ                           └─┘
1263  have exi2 : ∃ y, c = d * y, from hcd,
id                            └─┘
src                      
typ                           └─┘
1264  if hb : b = 0 then by simp [hb]
id   └┘                        └┘
src  └┘                   └────┘  └┘
typ  └┘                  └────┘└┘└┘
doc                        └────┘  └┘
txt                        └────┘  └┘
par                        └────┘  └┘
pid                              
st                        └─────────┘
1265  else have 0 < b, from nat.pos_of_ne_zero hb,
id        └──┘           └────────────────┘ └┘
src                       └────────────────┘
typ       └──┘           └────────────────┘ └┘
1266  if hd : d = 0 then by simp [hd]
id   └┘                        └┘
src  └┘                   └────┘  └┘
typ  └┘                  └────┘└┘└┘
doc                        └────┘  └┘
txt                        └────┘  └┘
par                        └────┘  └┘
pid                              
st                        └─────────┘
1267  else have 0 < d, from nat.pos_of_ne_zero hd,
id        └──┘           └────────────────┘ └┘
src                       └────────────────┘
typ       └──┘           └────────────────┘ └┘
1268  begin
st   └─────
1269    cases exi1 with x hx, cases exi2 with y hy,
id           └──┘                  └──┘
src    └────┘    └────────┘  └────┘    └────────┘
typ    └────┘└──┘└────────┘  └────┘└──┘└────────┘
doc    └────┘    └────────┘  └────┘    └────────┘
txt    └────┘    └────────┘  └────┘    └────────┘
par    └────┘    └────────┘  └────┘    └────────┘
pid             └────────┘           └────────┘
st   ─────────────────────┘└────────────────────┘└─
1270    rw [hx, hy, nat.mul_div_cancel_left, nat.mul_div_cancel_left],
id         └┘  └┘  └─────────────────────┘  └─────────────────────┘
src    └──┘  └┘  └┘└─────────────────────┘└┘└─────────────────────┘
typ    └──┘└┘└┘└┘└┘└─────────────────────┘└┘└─────────────────────┘
doc    └──┘  └┘  └┘                       └┘                       
txt    └──┘  └┘  └┘                       └┘                       
par    └──┘  └┘  └┘                       └┘                       
pid      └┘  └┘  └┘                       └┘                       
st   ───────┘└──┘└───────────────────────┘└───────────────────────┘└──
1271    symmetry,
src    └──────┘
typ    └──────┘
doc    └──────┘
txt    └──────┘
par    └──────┘
st   ─────────┘└─
1272    apply nat.div_eq_of_eq_mul_left,
id           └───────────────────────┘
src    └────┘└───────────────────────┘
typ    └────┘└───────────────────────┘
doc    └────┘
txt    └────┘
par    └────┘
pid         
st   ────────────────────────────────┘└─
1273    apply mul_pos,
id           └─────┘
src    └────┘└─────┘
typ    └────┘└─────┘
doc    └────┘
txt    └────┘
par    └────┘
pid         
st   ──────────────┘└─
1274    repeat {assumption},
src    └──────┘└────────┘
typ    └──────┘└────────┘
doc    └──────┘└────────┘
txt    └──────┘└────────┘
par    └──────┘└────────┘
pid          └───────────┘
st   ─────────┘└────────┘└┘
1275    cc
src    └─┘
typ    └─┘
doc    └─┘
txt    └─┘
par    └─┘
pid      
st   ────┘
1276  end
st   └─┘
1277  
1278  lemma pow_dvd_of_le_of_pow_dvd {p m n k : ℕ} (hmn : m ≤ n) (hdiv : p ^ n ∣ k) : p ^ m ∣ k :=
id                                                                              
src                                                                                   
typ                                                                             
1279  have p ^ m ∣ p ^ n, from pow_dvd_pow _ hmn,
id                     └─────────┘   └─┘
src                        └─────────┘
typ                    └─────────┘   └─┘
1280  dvd_trans this hdiv
id   └───────┘ └──┘ └──┘
src  └───────┘
typ  └───────┘ └──┘ └──┘
1281  
1282  lemma dvd_of_pow_dvd {p k m : ℕ} (hk : 1 ≤ k) (hpk : p^k ∣ m) : p ∣ m :=
id                                                             
src                                                                
typ                                                            
1283  by rw ←nat.pow_one p; exact pow_dvd_of_le_of_pow_dvd hk hpk
id          └─────────┘         └──────────────────────┘ └┘ └─┘
src     └──┘└─────────┘   └────┘└──────────────────────┘     
typ     └──┘└─────────┘  └────┘└──────────────────────┘└┘└─┘
doc     └──┘              └────┘                             
txt     └──┘              └────┘                             
par     └──┘              └────┘                             
pid       └┘                                                
st     └─────────────────────────────────────────────────────────
1284  
src  
typ  
doc  
txt  
par  
pid  
st   
1285  lemma eq_of_dvd_of_div_eq_one {a b : ℕ} (w : a ∣ b) (h : b / a = 1) : a = b :=
id                                                                   
src                                                                      
typ                                                                  
1286  by rw [←nat.div_mul_cancel w, h, one_mul]
id           └────────────────┘     └─────┘
src     └───┘└────────────────┘ └┘ └┘└─────┘└─
typ     └───┘└────────────────┘└┘└┘└─────┘└─
doc     └───┘                   └┘ └┘       └─
txt     └───┘                   └┘ └┘       └─
par     └───┘                   └┘ └┘       └─
pid       └─┘                   └┘ └┘       
st     └────────────────────────┘└─┘└───────┘
1287  
src  
typ  
doc  
txt  
par  
pid  
st   
1288  lemma eq_zero_of_dvd_of_div_eq_zero {a b : ℕ} (w : a ∣ b)  (h : b / a = 0) : b = 0 :=
id                                                                         
src                                                                             
typ                                                                        
1289  by rw [←nat.div_mul_cancel w, h, zero_mul]
id           └────────────────┘     └──────┘
src     └───┘└────────────────┘ └┘ └┘└──────┘└─
typ     └───┘└────────────────┘└┘└┘└──────┘└─
doc     └───┘                   └┘ └┘        └─
txt     └───┘                   └┘ └┘        └─
par     └───┘                   └┘ └┘        └─
pid       └─┘                   └┘ └┘        
st     └────────────────────────┘└─┘└────────┘
1290  
src  
typ  
doc  
txt  
par  
pid  
st   
1291  lemma div_le_div_left {a b c : ℕ} (h₁ : c ≤ b) (h₂ : 0 < c) : a / b ≤ a / c :=
id                                                                 
src                                                                     
typ                                                                
1292  (nat.le_div_iff_mul_le _ _ h₂).2 $
id    └───────────────────┘     └┘ 
src   └───────────────────┘        
typ   └───────────────────┘     └┘ 
1293    le_trans (mul_le_mul_left _ h₁) (div_mul_le_self _ _)
id     └──────┘  └─────────────┘   └┘   └─────────────┘
src    └──────┘  └─────────────┘        └─────────────┘
typ    └──────┘  └─────────────┘   └┘   └─────────────┘
1294  
1295  lemma div_eq_self {a b : ℕ} : a / b = a ↔ a = 0 ∨ b = 1 :=
id                                            
src                                                
typ                                           
1296  begin
st   └─────
1297    split,
src    └───┘
typ    └───┘
doc    └───┘
txt    └───┘
par    └───┘
st   ──────┘└─
1298    { intro,
src      └───┘
typ      └───┘
doc      └───┘
txt      └───┘
par      └───┘
st   ───┘└───┘└─
1299      cases b,
id             
src      └────┘
typ      └────┘
doc      └────┘
txt      └────┘
par      └────┘
pid           
st   ──────────┘└─
1300      { simp * at * },
src        └──────────┘
typ        └──────────┘
doc        └──────────┘
txt        └──────────┘
par        └──────────┘
pid            └──┘
st   ─────┘└──────────┘└┘
1301      { cases b,
id               
src        └────┘
typ        └────┘
doc        └────┘
txt        └────┘
par        └────┘
pid             
st   ────────────┘└─
1302        { right, refl },
src          └───┘  └───┘
typ          └───┘  └───┘
doc          └───┘  └───┘
txt          └───┘  └───┘
par          └───┘  └───┘
pid                     
st   ───────┘└───┘└─────┘└┘
1303        { left,
src          └──┘
typ          └──┘
doc          └──┘
txt          └──┘
par          └──┘
st   ───────────┘└─
1304          have : a / (b + 2) ≤ a / 2 := div_le_div_left (by simp) dec_trivial,
id                                    └─────────────┘           └─────────┘
src          └─────┘   └──┘  └────┘└─────────────┘   └──┘└┘└─────────┘
typ          └─────┘  └──┘ └────┘└─────────────┘   └──┘└┘└─────────┘
doc          └─────┘     └──┘   └────┘                  └──┘└┘└─────────┘
txt          └─────┘     └──┘   └────┘                  └──┘└┘
par          └─────┘     └──┘   └────┘                  └──┘└┘
pid          └───┘└┘     └──┘   └───┘                  └─────┘
st   ────────────────────────────────────────────────────────┘└───┘└───────────┘└─
1305          refine eq_zero_of_le_half _,
id                  └────────────────┘
src          └─────┘└────────────────┘└┘
typ          └─────┘└────────────────┘└┘
doc          └─────┘                  └┘
txt          └─────┘                  └┘
par          └─────┘                  └┘
pid                                  └┘
st   ──────────────────────────────────┘└─
1306          simp * at * } } },
src          └──────────┘
typ          └──────────┘
doc          └──────────┘
txt          └──────────┘
par          └──────────┘
pid              └──┘
st   ───────────────────┘└────┘
1307    { rintros (rfl|rfl); simp }
src      └───────────────┘  └───┘
typ      └───────────────┘  └───┘
doc      └───────────────┘  └───┘
txt      └───────────────┘  └───┘
par      └───────────────┘  └───┘
pid             └────────┘      
st   ───────────────────────────┘└─
1308  end
st   ──┘
1309  
1310  end div
1311  
1312  lemma exists_eq_add_of_le : ∀ {m n : ℕ}, m ≤ n → ∃ k : ℕ, n = m + k
id                                                         
src                                                            
typ                                                        
1313  | 0 0 h := ⟨0, by simp⟩
src                    └──┘
typ                    └──┘
doc                    └──┘
txt                    └──┘
par                    └──┘
st                    └───┘
1314  | 0 (n+1) h := ⟨n+1, by simp⟩
id                  
src                        └──┘
typ                       └──┘
doc                          └──┘
txt                          └──┘
par                          └──┘
st                          └───┘
1315  | (m+1) (n+1) h := let ⟨k, hk⟩ := exists_eq_add_of_le (nat.le_of_succ_le_succ h) in ⟨k, by simp [hk]⟩
id                   └─┘           └─────────────────┘  └────────────────────┘                    └┘
src                                                       └────────────────────┘              └────┘  
typ                  └─┘           └─────────────────┘  └────────────────────┘              └────┘└┘
doc                                                                                             └────┘  
txt                                                                                             └────┘  
par                                                                                             └────┘  
pid                                                                                                   
st                                                                                             └────────┘
1316  
1317  lemma exists_eq_add_of_lt : ∀ {m n : ℕ}, m < n → ∃ k : ℕ, n = m + k + 1
id                                                          
src                                                               
typ                                                         
1318  | 0 0 h := false.elim $ lt_irrefl _ h
id             └────────┘   └───────┘
src             └────────┘   └───────┘
typ            └────────┘   └───────┘
1319  | 0 (n+1) h := ⟨n, by simp⟩
id        
src                       └──┘
typ                      └──┘
doc                        └──┘
txt                        └──┘
par                        └──┘
st                        └───┘
1320  | (m+1) (n+1) h := let ⟨k, hk⟩ := exists_eq_add_of_le (nat.le_of_succ_le_succ h) in ⟨k, by simp [hk]⟩
id                   └─┘           └─────────────────┘  └────────────────────┘                    └┘
src                                  └─────────────────┘  └────────────────────┘              └────┘  
typ                  └─┘           └─────────────────┘  └────────────────────┘              └────┘└┘
doc                                                                                             └────┘  
txt                                                                                             └────┘  
par                                                                                             └────┘  
pid                                                                                                   
st                                                                                             └────────┘
1321  
1322  lemma with_bot.add_eq_zero_iff : ∀ {n m : with_bot ℕ}, n + m = 0 ↔ n = 0 ∧ m = 0
id                                            └──────┘                 
src                                            └──────┘                     
typ                                           └──────┘                 
1323  | none     m        := iff_of_false dec_trivial (λ h, absurd h.1 dec_trivial)
id     └──┘                 └──────────┘ └─────────┘      └────┘   └─────────┘
src    └──┘                 └──────────┘ └─────────┘       └────┘    └─────────┘
typ    └──┘                 └──────────┘ └─────────┘      └────┘   └─────────┘
doc                                      └─────────┘                  └─────────┘
1324  | n        none     := iff_of_false (by cases n; exact dec_trivial)
id              └──┘        └──────────┘                   └─────────┘
src             └──┘        └──────────┘     └────┘   └────┘└─────────┘
typ             └──┘        └──────────┘     └────┘  └────┘└─────────┘
doc                                          └────┘   └────┘└─────────┘
txt                                          └────┘   └────┘
par                                          └────┘   └────┘
pid                                                       
st                                          └─────────────────────────┘
1325    (λ h, absurd h.2 dec_trivial)
id          └────┘   └─────────┘
src          └────┘    └─────────┘
typ         └────┘   └─────────┘
doc                     └─────────┘
1326  | (some n) (some m) := show (n + m : with_bot ℕ) = (0 : ℕ) ↔ (n : with_bot ℕ) = (0 : ℕ) ∧
id              └──┘                   └──────┘                 └──────┘           
src              └──┘                    └──────┘                 └──────┘           
typ             └──┘                   └──────┘                 └──────┘           
1327      (m : with_bot ℕ) = (0 : ℕ),
id            └──────┘         
src           └──────┘         
typ           └──────┘         
1328    by rw [← with_bot.coe_add, with_bot.coe_eq_coe, with_bot.coe_eq_coe,
id              └──────────────┘  └─────────────────┘  └─────────────────┘
src       └────┘└──────────────┘└┘└─────────────────┘└┘└─────────────────┘└─
typ       └────┘└──────────────┘└┘└─────────────────┘└┘└─────────────────┘└─
doc       └────┘                └┘                   └┘                   └─
txt       └────┘                └┘                   └┘                   └─
par       └────┘                └┘                   └┘                   └─
pid         └──┘                └┘                   └┘                   └─
st       └─────────────────────┘└───────────────────┘└───────────────────┘└─
1329      with_bot.coe_eq_coe, add_eq_zero_iff' (nat.zero_le _) (nat.zero_le _)]
id       └─────────────────┘  └──────────────┘                  └─────────┘
src  ───┘└─────────────────┘└┘└──────────────┘            └──┘ └─────────┘└────
typ  ───┘└─────────────────┘└┘└──────────────┘            └──┘ └─────────┘└────
doc  ───┘                   └┘                            └──┘            └────
txt  ───┘                   └┘                            └──┘            └────
par  ───┘                   └┘                            └──┘            └────
pid  ───┘                   └┘                            └──┘            └──┘
st   ──────────────────────┘└────────────────────────────────────────────────┘
1330  
src  
typ  
doc  
txt  
par  
pid  
st   
1331  lemma with_bot.add_eq_one_iff : ∀ {n m : with_bot ℕ}, n + m = 1 ↔ (n = 0 ∧ m = 1) ∨ (n = 1 ∧ m = 0)
id                                           └──────┘                              
src                                           └──────┘                                    
typ                                          └──────┘                              
1332  | none     none     := dec_trivial
id              └──┘        └─────────┘
src             └──┘        └─────────┘
typ             └──┘        └─────────┘
doc                         └─────────┘
1333  | none     (some m) := dec_trivial
id     └──┘      └──┘       └─────────┘
src    └──┘      └──┘       └─────────┘
typ    └──┘      └──┘       └─────────┘
doc                         └─────────┘
1334  | (some n) none     := iff_of_false dec_trivial (λ h, h.elim (λ h, absurd h.2 dec_trivial)
id      └──┘    └──┘        └──────────┘ └─────────┘      └───┘      └────┘   └─────────┘
src     └──┘    └──┘        └──────────┘ └─────────┘        └───┘       └────┘    └─────────┘
typ     └──┘    └──┘        └──────────┘ └─────────┘      └───┘      └────┘   └─────────┘
doc                                      └─────────┘                               └─────────┘
1335    (λ h, absurd h.2 dec_trivial))
id          └────┘   └─────────┘
src          └────┘    └─────────┘
typ         └────┘   └─────────┘
doc                     └─────────┘
1336  | (some n) (some 0) := by erw [with_bot.coe_eq_coe, with_bot.coe_eq_coe, with_bot.coe_eq_coe,
id               └──┘               └─────────────────┘  └─────────────────┘  └─────────────────┘
src              └──┘          └───┘└─────────────────┘└┘└─────────────────┘└┘└─────────────────┘└─
typ              └──┘          └───┘└─────────────────┘└┘└─────────────────┘└┘└─────────────────┘└─
doc                            └───┘                   └┘                   └┘                   └─
txt                            └───┘                   └┘                   └┘                   └─
par                            └───┘                   └┘                   └┘                   └─
pid                               └┘                   └┘                   └┘                   └─
st                            └───────────────────────┘└───────────────────┘└───────────────────┘└─
1337      with_bot.coe_eq_coe]; simp
id       └─────────────────┘
src  ───┘└─────────────────┘  └───┘
typ  ───┘└─────────────────┘  └───┘
doc  ───┘                     └───┘
txt  ───┘                     └───┘
par  ───┘                     └───┘
pid  ───┘                         
st   ──────────────────────┘└─────┘
1338  | (some n) (some (m + 1)) := by erw [with_bot.coe_eq_coe, with_bot.coe_eq_coe, with_bot.coe_eq_coe,
id               └──┘                    └─────────────────┘  └─────────────────┘  └─────────────────┘
src              └──┘               └───┘└─────────────────┘└┘└─────────────────┘└┘└─────────────────┘└─
typ              └──┘               └───┘└─────────────────┘└┘└─────────────────┘└┘└─────────────────┘└─
doc                                  └───┘                   └┘                   └┘                   └─
txt                                  └───┘                   └┘                   └┘                   └─
par                                  └───┘                   └┘                   └┘                   └─
pid                                     └┘                   └┘                   └┘                   └─
st                                  └───────────────────────┘└───────────────────┘└───────────────────┘└─
1339      with_bot.coe_eq_coe, with_bot.coe_eq_coe]; simp [nat.add_succ, nat.succ_inj', nat.succ_ne_zero]
id       └─────────────────┘  └─────────────────┘         └──────────┘  └───────────┘  └──────────────┘
src  ───┘└─────────────────┘└┘└─────────────────┘  └────┘└──────────┘└┘└───────────┘└┘└──────────────┘└─
typ  ───┘└─────────────────┘└┘└─────────────────┘  └────┘└──────────┘└┘└───────────┘└┘└──────────────┘└─
doc  ───┘                   └┘                     └────┘            └┘             └┘                └─
txt  ───┘                   └┘                     └────┘            └┘             └┘                └─
par  ───┘                   └┘                     └────┘            └┘             └┘                └─
pid  ───┘                   └┘                                     └┘             └┘                
st   ──────────────────────┘└───────────────────┘└──────────────────────────────────────────────────────
1340  
src  
typ  
doc  
txt  
par  
pid  
st   
1341  -- induction
src  ─────────────
typ  ─────────────
doc  ─────────────
txt  ─────────────
par  ─────────────
pid  ─────────────
st   ─────────────
1342  
src  
typ  
doc  
txt  
par  
pid  
st   
1343  /-- Induction principle starting at a non-zero number. For maps to a `Sort*` see `le_rec_on`. -/
1344  @[elab_as_eliminator] lemma le_induction {P : nat → Prop} {m} (h0 : P m) (h1 : ∀ n, m ≤ n → P n → P (n + 1)) :
id                                                 └─┘                                            
src                                                └─┘                                                     
typ                                                └─┘                                            
doc    └────────────────┘
1345    ∀ n, m ≤ n → P n :=
id               
src           
typ              
1346  by apply nat.less_than_or_equal.rec h0; exact h1
id            └────────────────────────┘ └┘        └┘
src     └────┘└────────────────────────┘    └────┘  
typ     └────┘└────────────────────────┘└┘  └────┘└┘
doc     └────┘                              └────┘  
txt     └────┘                              └────┘  
par     └────┘                              └────┘  
pid                                               
st     └──────────────────────────────────────────────
1347  
src  
typ  
doc  
txt  
par  
pid  
st   
1348  /-- Decreasing induction: if `P (k+1)` implies `P k`, then `P n` implies `P m` for all `m ≤ n`.
1349  Also works for functions to `Sort*`. -/
1350  @[elab_as_eliminator]
doc    └────────────────┘
1351  def decreasing_induction {P : ℕ → Sort*} (h : ∀n, P (n+1) → P n) {m n : ℕ} (mn : m ≤ n)
id                                                                              
src                                                                                  
typ                                                                             
1352    (hP : P n) : P m :=
id                 
typ                
1353  le_rec_on mn (λ k ih hsk, ih $ h k hsk) (λ h, h) hP
id   └───────┘ └┘     └┘ └─┘  └┘     └─┘         └┘
src  └───────┘
typ  └───────┘ └┘     └┘ └─┘  └┘     └─┘         └┘
doc  └───────┘
1354  
1355  @[simp] lemma decreasing_induction_self {P : ℕ → Sort*} (h : ∀n, P (n+1) → P n) {n : ℕ}
id                                                                                 
src                                                                                     
typ                                                                                
doc    └──┘
1356    (nn : n ≤ n) (hP : P n) : (decreasing_induction h nn hP : P n) = hP :=
id                           └──────────────────┘  └┘ └┘       └┘
src                              └──────────────────┘                
typ                          └──────────────────┘  └┘ └┘       └┘
doc                               └──────────────────┘
1357  by { dunfold decreasing_induction, rw [le_rec_on_self] }
id                                          └────────────┘
src       └──────────────────────────┘  └──┘└────────────┘└┘
typ       └──────────────────────────┘  └──┘└────────────┘└┘
doc       └──────────────────────────┘  └──┘              └┘
txt       └──────────────────────────┘  └──┘              └┘
par       └──────────────────────────┘  └──┘              └┘
pid              └───────────────────┘    └┘              
st     └─────────────────────────────┘└──────────────────┘└┘
1358  
1359  lemma decreasing_induction_succ {P : ℕ → Sort*} (h : ∀n, P (n+1) → P n) {m n : ℕ} (mn : m ≤ n)
id                                                                                     
src                                                                                         
typ                                                                                    
1360    (msn : m ≤ n + 1) (hP : P (n+1)) :
id                           
src                              
typ                          
1361    (decreasing_induction h msn hP : P m) = decreasing_induction h mn (h n hP) :=
id      └──────────────────┘  └─┘ └┘       └──────────────────┘  └┘    └┘
src     └──────────────────┘                  └──────────────────┘
typ     └──────────────────┘  └─┘ └┘       └──────────────────┘  └┘    └┘
doc     └──────────────────┘                   └──────────────────┘
1362  by { dunfold decreasing_induction, rw [le_rec_on_succ] }
id                                          └────────────┘
src       └──────────────────────────┘  └──┘└────────────┘└┘
typ       └──────────────────────────┘  └──┘└────────────┘└┘
doc       └──────────────────────────┘  └──┘              └┘
txt       └──────────────────────────┘  └──┘              └┘
par       └──────────────────────────┘  └──┘              └┘
pid              └───────────────────┘    └┘              
st     └─────────────────────────────┘└──────────────────┘└┘
1363  
1364  @[simp] lemma decreasing_induction_succ' {P : ℕ → Sort*} (h : ∀n, P (n+1) → P n) {m : ℕ}
id                                                                                  
src                                                                                      
typ                                                                                 
doc    └──┘
1365    (msm : m ≤ m + 1) (hP : P (m+1)) : (decreasing_induction h msm hP : P m) = h m hP :=
id                                  └──────────────────┘  └─┘ └┘         └┘
src                                     └──────────────────┘                 
typ                                 └──────────────────┘  └─┘ └┘         └┘
doc                                        └──────────────────┘
1366  by { dunfold decreasing_induction, rw [le_rec_on_succ'] }
id                                          └─────────────┘
src       └──────────────────────────┘  └──┘└─────────────┘└┘
typ       └──────────────────────────┘  └──┘└─────────────┘└┘
doc       └──────────────────────────┘  └──┘               └┘
txt       └──────────────────────────┘  └──┘               └┘
par       └──────────────────────────┘  └──┘               └┘
pid              └───────────────────┘    └┘               
st     └─────────────────────────────┘└───────────────────┘└┘
1367  
1368  lemma decreasing_induction_trans {P : ℕ → Sort*} (h : ∀n, P (n+1) → P n) {m n k : ℕ}
id                                                                              
src                                                                                  
typ                                                                             
1369    (mn : m ≤ n) (nk : n ≤ k) (hP : P k) :
id                                
src                        
typ                               
1370    (decreasing_induction h (le_trans mn nk) hP : P m) =
id      └──────────────────┘   └──────┘ └┘ └┘  └┘      
src     └──────────────────┘    └──────┘                  
typ     └──────────────────┘   └──────┘ └┘ └┘  └┘      
doc     └──────────────────┘
1371    decreasing_induction h mn (decreasing_induction h nk hP) :=
id     └──────────────────┘  └┘  └──────────────────┘  └┘ └┘
src    └──────────────────┘       └──────────────────┘
typ    └──────────────────┘  └┘  └──────────────────┘  └┘ └┘
doc    └──────────────────┘       └──────────────────┘
1372  by { induction nk with k nk ih, rw [decreasing_induction_self],
id                  └┘                   └───────────────────────┘
src       └────────┘  └───────────┘  └──┘└───────────────────────┘
typ       └────────┘└┘└───────────┘  └──┘└───────────────────────┘
doc       └────────┘  └───────────┘  └──┘                         
txt       └────────┘  └───────────┘  └──┘                         
par       └────────┘  └───────────┘  └──┘                         
pid                  └──────────┘    └┘                         
st     └──────────────────────────┘└────┘└───────────────────────┘└─
1373       rw [decreasing_induction_succ h (le_trans mn nk), ih, decreasing_induction_succ] }
id            └───────────────────────┘   └──────┘ └┘ └┘   └┘  └───────────────────────┘
src       └──┘└───────────────────────┘  └──────┘    └─┘  └┘└───────────────────────┘└┘
typ       └──┘└───────────────────────┘ └──────┘└┘└┘└─┘└┘└┘└───────────────────────┘└┘
doc       └──┘                                       └─┘  └┘                         └┘
txt       └──┘                                       └─┘  └┘                         └┘
par       └──┘                                       └─┘  └┘                         └┘
pid         └┘                                       └─┘  └┘                         
st   ────────────────────────────────────────────────────┘└──┘└─────────────────────────┘└┘
1374  
1375  lemma decreasing_induction_succ_left {P : ℕ → Sort*} (h : ∀n, P (n+1) → P n) {m n : ℕ}
id                                                                                
src                                                                                    
typ                                                                               
1376    (smn : m + 1 ≤ n) (mn : m ≤ n) (hP : P n) :
id                                    
src                            
typ                                   
1377    (decreasing_induction h mn hP : P m) = h m (decreasing_induction h smn hP) :=
id      └──────────────────┘  └┘ └┘          └──────────────────┘  └─┘ └┘
src     └──────────────────┘                      └──────────────────┘
typ     └──────────────────┘  └┘ └┘          └──────────────────┘  └─┘ └┘
doc     └──────────────────┘                       └──────────────────┘
1378  by { rw [subsingleton.elim mn (le_trans (le_succ m) smn), decreasing_induction_trans,
id            └───────────────┘ └┘  └──────┘  └─────┘   └─┘   └────────────────────────┘
src       └──┘└───────────────┘   └──────┘ └─────┘ └┘   └─┘└────────────────────────┘└─
typ       └──┘└───────────────┘└┘ └──────┘ └─────┘└┘└─┘└─┘└────────────────────────┘└─
doc       └──┘                                     └┘   └─┘                          └─
txt       └──┘                                     └┘   └─┘                          └─
par       └──┘                                     └┘   └─┘                          └─
pid         └┘                                     └┘   └─┘                          └─
st     └────────────────────────────────────────────────────┘└──────────────────────────┘└─
1379           decreasing_induction_succ'] }
id            └────────────────────────┘
src  ────────┘└────────────────────────┘└┘
typ  ────────┘└────────────────────────┘└┘
doc  ────────┘                          └┘
txt  ────────┘                          └┘
par  ────────┘                          └┘
pid  ────────┘                          
st   ──────────────────────────────────┘└┘
1380  
1381  end nat